Dunedubby
Dunedubby

Reputation: 149

Is it safe to point to an array access from a pointer that goes beyond the array?

Apologies for the loopy question wording, but it boils down to this. I'm maintaining C code that does something like this:

char *foo = "hello"
int i;
char *bar;

i = strlen(foo);
bar = &foo[i];

Is this safe? Could there be a case where the foo[i] leads to a segmentation fault, before it gets a pointer, and isn't covered by the compiler?

Upvotes: 1

Views: 72

Answers (2)

John Bollinger
John Bollinger

Reputation: 181149

I'm maintaining C code that does something like this:

char *foo = "hello"
int i;
char *bar;

i = strlen(foo);
bar = &foo[i];

Is this safe?

The code presented conforms with the current and all past C language standards, and has the same well-defined behavior according to each. In particular, be aware that C string literals represent null-terminated character arrays, just like all other C strings, so in the example code. foo[i] refers to the terminator, and &foo[i] points into the array (to its last element), not outside it.

Moreover, C also allows obtaining a pointer to just past the end of an array, so even 1 + &foo[i] is valid and conforming. It is not permitted to dereference such a pointer, but you can perform pointer arithmetic and comparisons with it (subject to the normal constraints).

Could there be a case where the foo[i] leads to a segmentation fault, before it gets a pointer, and isn't covered by the compiler?

C does not have anything whatever to say about segmentation faults. Whenever you receive one, either your implementation has exhibited non-conformance, or (almost always) your program is exercising undefined behavior. The code presented conforms, subject to a correct declaration of strlen() being in scope, and if it appears as part of a complete program that conforms and does not otherwise exercise UB then there is no reason short of general skepticism to fear a segfault.

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234795

Yes, you are allowed to set a pointer one beyond the end of an array (although you are not actually doing that in your code - you are pointing to the NUL terminator).

Note though that the behaviour on dereferencing a pointer set to one past the end of an array would be undefined.

(Note that &foo[i] is required by the C standard to be evaluated without dereferencing the pointer: i.e. &foo[i + 1] is valid, but foo[i + 1] on its own isn't.)

Upvotes: 5

Related Questions