0

Given a pointer-to-array in C, can we malloc to it enough memory for extra elements (beyond the specified array size) and then safely access those elements using either the [] operator or pointer arithmetic?

Consider this example:

int (*foo)[ 10 ]; //Declare pointer to array of ten ints
foo = malloc( sizeof( int ) * 20 ); //Allocate memory for TWENTY ints
(*foo)[ 15 ] = 100; //Access element in "extra" space via [] operator 
*( *foo + 16 ) = 200; //Access element in "extra" space via pointer arithmetic
printf( "%d\n", *( *foo + 15 ) ); //Prints 100
printf( "%d\n", (*foo)[ 16 ] ); //Prints 200

This code compiles fine and produces correct results in gcc. However, I'm not sure if it invokes undefined behavior.

Thanks!

Jackson Allan
  • 727
  • 3
  • 11

2 Answers2

2

What you're doing trigger undefined behavior because you're reading/writing past the bounds of an array of int of size 10.

The proper way to access this memory is to use 2D array access. So instead of this:

(*foo)[15] = 100;

Which is equivalent to this:

foo[0][15] = 100;

Do this:

foo[1][5] = 100;
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thanks for the response. Are you sure the out-of-bounds access rule applies to the pointer arithmetic version?: ( *foo + n ). *foo + 0 decays to int pointer pointing the first element in the array. However, it's also an int pointer to the beginning of a malloced bloc of memory, which the the standards seem to treat as an "array object" and which I should - in theory - be able to move around inside freely using pointer arithmetic. – Jackson Allan Oct 31 '21 at 01:15
  • As for the proper/usual way, it's not quite relevant because the idea I'm exploring here is that pointers-to-array could be used to tack extra, compile-time information (specifically an integer value) onto what would otherwise be a regular pointer. – Jackson Allan Oct 31 '21 at 01:16
  • 1
    @JacksonAllan The syntax `E1[E2]` is *exactly* equivalent to `*(E1 + E2)` so yes it applies. As for arithmetic into the allocated memory, if you assigned the malloced memory to a `char *`, do arithmetic on that, then convert the resulting pointer to the desired type, that would probably be OK since a `char *` gets special treatment. – dbush Oct 31 '21 at 01:26
0

I would allocate it a bit different way:

foo = malloc( sizeof( *foo ) * nrows );

it will allocate 2D array having 10 clomns and nrows rowas.

The best way to access the array is using indexes

foo[row][column]
0___________
  • 60,014
  • 4
  • 34
  • 74