Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is accessing the middle of a multidimensional array via a pointer to its first element UB?

Consider the following code:

int data[2][2];
int* p(&data[0][0]);
p[3] = 0;

Or equivalently:

int data[2][2];
int (&row0)[2] = data[0];
int* p = &row0[0];
p[3] = 0;

It's not clear to me whether this is undefined behaviour or not. p is a pointer to the first element of an array row0 with 2 elements, therefore p[3] accesses past the end of the array, which is UB according to 7.6.6 [expr.add]:

  • When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P.
    • If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
    • Otherwise, if P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0 ≤ i + jn and the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0 ≤ i − jn.
    • Otherwise, the behavior is undefined.

I don't see anything in the standard that gives special treatment to multidimensional arrays, so I can only conclude that the above is, in fact, UB.

Am I correct?

What about the case of data being declared as std::array<std::array<int, 2>, 2>? This case seems even more likely to be UB, as structs may have padding.

like image 237
P.JBoy Avatar asked Nov 28 '18 18:11

P.JBoy


People also ask

How pointers can be used for accessing multidimensional arrays?

Pointers and two dimensional Arrays: In a two dimensional array, we can access each element by using two subscripts, where first subscript represents the row number and second subscript represents the column number. The elements of 2-D array can be accessed with the help of pointer notation also.

How is multidimensional array defined in terms of pointer?

An element in a multidimensional array like two-dimensional array can be represented by pointer expression as follows: **a+i+jIt represent the element a[i][j]. The base address of the array a is &a[0][0] and starting at this address the compiler allocates contiguous space for all the element row-wise.

How can a pointer be used to access individual elements of an array?

Access Array Elements Using Pointers In this program, the elements are stored in the integer array data[] . Then, the elements of the array are accessed using the pointer notation. By the way, data[0] is equivalent to *data and &data[0] is equivalent to data.

How is the 2nd element in an array accessed based on pointer notation?

To access the array's second element, we need to add 1 to the first row of the array as follows: *(matrix[0] + 1) . The expression, matrix[0] , returns the address of the first element of the first row of the array. This address is the address of an array of integers.


1 Answers

Yes, you are correct, and there is not much to add to it. There are no mutidimensional arrays in C++ type system, there are only arrays (of arrays of arrays of arrays ad libitum).

Accessing an element beyond array size is undefined behavior.

like image 159
SergeyA Avatar answered Oct 13 '22 01:10

SergeyA