473,508 Members | 2,477 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is out-of-bounds portable on a multidimensional array?

I've checked the FAQ for this and couldn't find the answer. Is the
following code snippet portable?

int a[10][10];
a[1][4]=6;
printf("%d\n",(*a)[14]);

This prints "6" on my compiler. I've been told it's always legal, but
it seems slightly suspect to me. Can you really go out-of-bounds like
this on one of the 'sub-arrays' a[0], a[1], etc.?

(N.B. To the pedants out there: this is not meant to be a complete
program, just part of one.)

Jan 26 '06 #1
8 1813
ais523 wrote:
I've checked the FAQ for this and couldn't find the answer. Is the
following code snippet portable?

int a[10][10];
a[1][4]=6;
printf("%d\n",(*a)[14]);

This prints "6" on my compiler. I've been told it's always legal, but
it seems slightly suspect to me. Can you really go out-of-bounds like
this on one of the 'sub-arrays' a[0], a[1], etc.?
This has been discussed here before at length with strong opinions in
moth directions. I think that it is technically undefined behaviour but
will only fail on implementations that go out of their way to do bounds
checking.

I think that the following might be OK though:
int a[10][10];
a[1][4]=6;
printf("%d\n",((int*)a)[14]);
A rough reasoning being that a must be properly aligned for an int*, so
we know the conversion will work and also obviously know it will point
to the first element of the first sub-array. Also the size of an array
is guaranteed to be the number of elements times the size of each
elements, which does not leave any room for padding to be inserted.
Finally, the array a is one object, so we are not leaving the object we
are pointing to.

Note, the last of these does not necessarily apply without the cast to
int* because a[0] is an object of type array of 10 ints.

Personally, I would be very dubious of code doing this unless there was
a very good justification for not treating it as a 2d array.
(N.B. To the pedants out there: this is not meant to be a complete
program, just part of one.)


You've obviously been reading this group since you've realised it is
full of pedants :-)
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 26 '06 #2
Flash Gordon wrote:
ais523 wrote:
I've checked the FAQ for this and couldn't find the answer. Is the
following code snippet portable?

int a[10][10];
a[1][4]=6;
printf("%d\n",(*a)[14]);

This prints "6" on my compiler. I've been told it's always legal, but
it seems slightly suspect to me. Can you really go out-of-bounds like
this on one of the 'sub-arrays' a[0], a[1], etc.?

This has been discussed here before at length with strong opinions in
moth directions. I think that it is technically undefined behaviour but
will only fail on implementations that go out of their way to do bounds
checking.

I think that the following might be OK though:
int a[10][10];
a[1][4]=6;
printf("%d\n",((int*)a)[14]);
A rough reasoning being that a must be properly aligned for an int*, so
we know the conversion will work and also obviously know it will point
to the first element of the first sub-array. Also the size of an array
is guaranteed to be the number of elements times the size of each
elements, which does not leave any room for padding to be inserted.
Finally, the array a is one object, so we are not leaving the object we
are pointing to.

Note, the last of these does not necessarily apply without the cast to
int* because a[0] is an object of type array of 10 ints.

Personally, I would be very dubious of code doing this unless there was
a very good justification for not treating it as a 2d array.
(N.B. To the pedants out there: this is not meant to be a complete
program, just part of one.)

You've obviously been reading this group since you've realised it is
full of pedants :-)

when seeking a bi-dimensional array of char (argv) going out-of-bounds,
i had a segmentation fault long before then end of the array

/* FIRST SEEK argv[i] : OK */
for (i=0; i<argc+1000; i++)
{
printf ("argv[%d] %s\n\n", i, argv[i]);
if ((i>argc) && (*(argv+i) == NULL))
{
printf ("FIN de Tab arg %d\n\n", i);
break;
}
}

/* THIS SEEK (char)(*argv)[i] : KO long before end of last array (69/86 but it depends on the previous code...) */
/* what's more seg fault occurs long after crossing from argv to envp... */
for (i=0; i<86*100; i++)
{
printf ("%c", (char)(*argv)[i]);
}

this trouble seems not occur with array of array of int ...

Xavier

Jan 26 '06 #3
serrand wrote:

<snip>

Your post did not have anything to do with mine. It is a completely
different situation.
when seeking a bi-dimensional array of char (argv) going out-of-bounds,
i had a segmentation fault long before then end of the array
argv is not a two-dimensional array, it is an array of pointers, a
*very* different thing. Read section 6 of the FAQ, particularly
questions 6.18 and 6.19
/* FIRST SEEK argv[i] : OK */
for (i=0; i<argc+1000; i++)
{
printf ("argv[%d] %s\n\n", i, argv[i]);
As soon as you hit the last element of argv you invoke undefined
behaviour since you pass a null pointer for the %s specifier. You invoke
it again as soon as you go beyond the end of argv.
if ((i>argc) && (*(argv+i) == NULL))
{
printf ("FIN de Tab arg %d\n\n", i);
break;
}
}

/* THIS SEEK (char)(*argv)[i] : KO long before end of last array
(69/86 but it depends on the previous code...) */
/* what's more seg fault occurs long after crossing from argv to
envp... */
for (i=0; i<86*100; i++)
{
printf ("%c", (char)(*argv)[i]);
}

this trouble seems not occur with array of array of int ...


I ran across Church Road without checking if it was clear and nothing
went wrong, but when I ran across Daws Hearth Road without checking I
got hit by a 10 tonne lorry and was in hospital for a week! Why does
this only happen when running across Daws Heath Road?

Answer, blind luck.

Don't read or write off the end of an array. Every. You don't try to
read the 300th page of a 200 page book do you? Or put 200 galleons of
petrol in the petrol tank of your car which doesn't take that much? So
why do you think it is OK to do the same thing with arrays in C?
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 26 '06 #4
Flash Gordon wrote:
argv is not a two-dimensional array, it is an array of pointers, a
*very* different thing. Read section 6 of the FAQ, particularly
questions 6.18 and 6.19 thanks too much !! it's the explanation i expected ...

I ran across Church Road without checking if it was clear and nothing
went wrong, but when I ran across Daws Hearth Road without checking I
got hit by a 10 tonne lorry and was in hospital for a week! Why does
this only happen when running across Daws Heath Road?

Answer, blind luck.

Don't read or write off the end of an array. Every. You don't try to
read the 300th page of a 200 page book do you? Or put 200 galleons of
petrol in the petrol tank of your car which doesn't take that much? So
why do you think it is OK to do the same thing with arrays in C?


when reading out-of-bounds...don't we try to read the 300th page of a 200 page book ?
We can if next place is another book of the same kind ...
with bi-dimensional array, sub-arrays are contiguous... then we can pass the bounds...
the same occurs when we are certain that elements (arrays...) are contiguous...
with union don't we do that thing ?

struct TAddr {
union {
unsigned char octs[4];
unsigned long int num_ip;
} ip;
};

but i'm always following your advice (as faq 6.19) ;-)

Xavier
Jan 26 '06 #5
On 2006-01-26, serrand <xa************@free.fr> wrote:
Flash Gordon wrote:
ais523 wrote:
I've checked the FAQ for this and couldn't find the answer. Is the
following code snippet portable?

int a[10][10];
a[1][4]=6;
printf("%d\n",(*a)[14]);

This prints "6" on my compiler. I've been told it's always legal, but
it seems slightly suspect to me. Can you really go out-of-bounds like
this on one of the 'sub-arrays' a[0], a[1], etc.?

This has been discussed here before at length with strong opinions in
moth directions. I think that it is technically undefined behaviour but
will only fail on implementations that go out of their way to do bounds
checking.

I think that the following might be OK though:
int a[10][10];
a[1][4]=6;
printf("%d\n",((int*)a)[14]);
A rough reasoning being that a must be properly aligned for an int*, so
we know the conversion will work and also obviously know it will point
to the first element of the first sub-array. Also the size of an array
is guaranteed to be the number of elements times the size of each
elements, which does not leave any room for padding to be inserted.
Finally, the array a is one object, so we are not leaving the object we
are pointing to.

Note, the last of these does not necessarily apply without the cast to
int* because a[0] is an object of type array of 10 ints.

Personally, I would be very dubious of code doing this unless there was
a very good justification for not treating it as a 2d array.
(N.B. To the pedants out there: this is not meant to be a complete
program, just part of one.)

You've obviously been reading this group since you've realised it is
full of pedants :-)

when seeking a bi-dimensional array of char (argv) going out-of-bounds,
i had a segmentation fault long before then end of the array


argv is not a "bi-dimensional array" in the sense required for the
original question to apply.
Jan 26 '06 #6
A multi-dimensional array is really just a single dimensional array
that lets itself be treated as a multi-dimensional one - it's stored in
memory contiguously - therefore allowing you do do what you just did. A
true multi-dimensional array is an array of pointers (some would argue
with this statement, though) - the memory layout is not contiguous,
excepet for the first index of course (..the pointers), and thus, you
would not be able to do the same out-of-bounds trick.

Jan 26 '06 #7
"relient" <xl***************@gmail.com> writes:
A multi-dimensional array is really just a single dimensional array
that lets itself be treated as a multi-dimensional one - it's stored in
memory contiguously - therefore allowing you do do what you just did. A
true multi-dimensional array is an array of pointers (some would argue
with this statement, though) - the memory layout is not contiguous,
excepet for the first index of course (..the pointers), and thus, you
would not be able to do the same out-of-bounds trick.


Context please! Read <http://cfaj.freeshell.org/google/>.

A multi-dimensional array is really an array of arrays. The standard
says enough about array layouts that we can be sure the rows are
allocated contiguously. Given

int arr[5][5];

we can be sure that arr[0][7], *if it's legal*, is at the same
location as arr[1][2]. But there might be enough ambiguity in the
standard to allow an implementation to do bounds checking in a way
that allows arr[1][2], but forbids arr[0][7]. Or there might not;
this has been the subject of some debate, and as far as I know it
hasn't really been resolved.

An array of pointers is *not* a "true multi-dimensional array"; it's
just an array of pointers. It can be used to implement something that
acts very much like a multi-dimensional array, but it isn't one. The
standard is clear on this point.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 26 '06 #8
serrand wrote:
Flash Gordon wrote:
<snip>
I ran across Church Road without checking if it was clear and nothing
went wrong, but when I ran across Daws Hearth Road without checking I
got hit by a 10 tonne lorry and was in hospital for a week! Why does
this only happen when running across Daws Heath Road?

Answer, blind luck.

Don't read or write off the end of an array. Every. You don't try to
read the 300th page of a 200 page book do you? Or put 200 galleons of
petrol in the petrol tank of your car which doesn't take that much? So
why do you think it is OK to do the same thing with arrays in C?


when reading out-of-bounds...don't we try to read the 300th page of a
200 page book ?
We can if next place is another book of the same kind ...


In C there is no guarantee what order object will be stored.
with bi-dimensional array, sub-arrays are contiguous... then we can pass
the bounds...
That is more like going to a different chapter in the same book. See
also Keith Thompson's reply to relient.
the same occurs when we are certain that elements (arrays...) are
contiguous...
with union don't we do that thing ?
I'm really not sure what you are trying to say here.
struct TAddr {
union {
unsigned char octs[4];
unsigned long int num_ip;
} ip;
};

but i'm always following your advice (as faq 6.19) ;-)


Good.

--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Jan 26 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
8621
by: FilexBB | last post by:
Hi Folks, I have tried to redirect system.out for a while and then set it back, but it can't set it back as following program snapshot ByteArrayOutputStream baos = new ByteArrayOutputStream();...
4
36730
by: Merlin | last post by:
Hi there, I would like to check if a string is a valid zip code via Javascript. Length and existents are already checked. How can I find out if the string contains characters other than...
5
8370
by: Mike Carroll | last post by:
I have a COM server that's generally working ok. But one of its methods, when the IDL gets read by the Intertop layer, has parameters of type "out object". The C# compiler tells me that it...
4
13780
by: Steve B. | last post by:
Hello I'm wondering what is exactly the difference between "ref" and "out" keywords. Thanks, Steve
2
2318
by: Chua Wen Ching | last post by:
Hi there, I am wondering the difference between attribute and out keywords. Are they the same or does it serve any different purposes? I saw the and out usage in this code, and i had idea,...
4
2358
by: Jon | last post by:
Why are out parmeters included in an BeginInvoke? They seem to do nothing? TestProgam: using System; namespace TempConsole { class App { public delegate void MyDelegate( out byte b, out...
14
7332
by: stic | last post by:
Hi, I'm in a middle of writing something like 'exception handler wraper' for a set of different methodes. The case is that I have ca. 40 methods form web servicem, with different return values...
6
5048
by: nick | last post by:
For example: public static void FillRow(Object obj, out SqlDateTime timeWritten, out SqlChars message, out SqlChars category, out long instanceId)
6
1491
by: selva | last post by:
hi, currently iam working on c# i need to pass a parameter inside a function which is a OUT parameter and i need to pass it as a reference how to do this? please help me regarding this...
6
14373
by: carlos123 | last post by:
Ok guys, check this out! Im getting an error "Error: Index: 0, Size: 0" not sure why. try{ // Create file FileWriter fstream = new FileWriter("database.txt"); BufferedWriter...
0
7231
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7405
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7066
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
5059
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3214
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3198
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1568
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
773
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
435
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.