0

I started learning C++ and I wanted to implement a simple 2D array and get its size without using std::vector. However I run into weird errors with my second dimension:

int **data= new int*[2];
for (int i = 0; i<2;i++){
    data[i] = new int[3];
}

data[0][0] = 1;
data[0][1] = 2;
data[0][2] = 3;

data[1][0] = 4;
data[1][1] = 5;
data[1][2] = 6;

data[1][25] = 20; //Should segfault? AAAAA

cout << "Data[1][25] = " << data[1][25] << endl; //Should segfault, no?

int n = sizeof(data[0]) / sizeof(int);
int m = sizeof(data) / sizeof(int);
cout << "M is " << m << " N is " << n << endl;// Reports m = 2, n =2?!?!? BBBB

At AAAA I should be getting segfault, no? Instead I am able to assign a value and later read it. The value of data[1][any] is zero, like it has been initialized. This is only a problem in the second dimension, the first dimension behaves as expected.

Later at BBBB I am not getting an accurate size for n. Am I doing something wrong?

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
XapaJIaMnu
  • 1,408
  • 3
  • 12
  • 28

5 Answers5

3

C++ does not do bound checking on arrays. Accessing data outside the bounds of an array is undefined behavior and anything can happen. It may cause a segfault it might not. If you have valid memory regions before or after the array you can end up accessing or modifying that memory instead. This can lead to corruption of other data used by your program.

Also you use of sizeof is incorrect. sizeof is a compile time construct. It cannot be used to determine the size of an array through a pointer value at runtime. If you need that type of functionality use std::array or std::vector.

char somearray[10];
int size = sizeof(somearray); // result is 10. Yay it works.

char *somearrayptr = new char[10];
int size = sizeof(somearrayptr);  // size = the size of char* not char[10].
Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
2

At AAAA you have undefined behavior. Just anything can happen from that point on -- and more interesting, even before.

In standard C++ there is no such behavior as 'segfault'. And implementation could define some operations to do that but I'm not aware if any ever bothered. It just happens by chance for some cases.

Balog Pal
  • 16,195
  • 2
  • 23
  • 37
1

Accessing an array outside its boundaries is undefined behavior. So there is no reason to expect anything in particular will happen: it could crash, return the right answer, return the wrong answer, silently corrupt data in another part of the program, or a whole host of other possibilities.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
1
data[1][25] = 20; //Should segfault? AAAAA

It would segfault if you are not allowed to access the location. There is no checking in C++ to see if the location you are accessing is valid frrm the code-point of view.

You obtained an output because that was stored at that location. It could have been anything. This is undefined behaviour and you may not get the same result everytime.

See this answer, though it talks abput local variables , but it gives nice examples about how such accessing of data can be undefined behaviour

data and data[0] are both pointers (doesn't matter single or double). They have a defined size for every implementation. In your case, size of pointer is twice that of size of int on your machine. Hence, the output. sizeof when used with pointers pointing to arrays (and not arrays i.e. ones declared as arrays char a[] etc) gives the size of the pointer

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
0

Both data[0] and data are pointers. Pointers will be size 4 on a 32-bit system, and 8 on a 64-bit system. Therefore, m and n are equal. Size of int is always 4.

dijkstra
  • 1,068
  • 2
  • 16
  • 39