我开始学习C ++,我想实现一个简单的2D数组并在不使用std::vector
的情况下获得它的大小。但是我的第二个维度遇到了奇怪的错误:
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
在AAAA
我应该得到段错误,不是吗?相反,我能够分配一个值,然后再读取它。 data[1][any]
的值为零,就像它已初始化一样。这只是第二个维度的问题,第一个维度的行为符合预期。
稍后BBBB
我无法获得n
的准确大小。我做错了吗?
答案 0 :(得分:3)
C ++不对数组进行绑定检查。访问数组边界之外的数据是未定义的行为,任何事情都可能发生。 可能导致它可能不会发生段错误。如果在阵列之前或之后有有效的内存区域,则可以最终访问或修改该内存。这可能会导致程序使用的其他数据损坏。
您使用sizeof
也是错误的。 sizeof
是编译时构造。它不能用于在运行时通过指针值确定数组的大小。如果您需要此类功能,请使用std::array
或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].
答案 1 :(得分:2)
在AAAA,您有未定义的行为。从那时起,任何事情都可能发生 - 甚至在此之前更有趣。
在标准C ++中,没有'segfault'这样的行为。并且实现可以定义一些操作来做到这一点,但我不知道是否有任何困扰。对于某些情况,它只是偶然发生。
答案 2 :(得分:1)
访问其边界之外的数组是未定义的行为。所以没有理由期待任何特别的事情会发生:它可能崩溃,返回正确的答案,返回错误的答案,无声地破坏程序的另一部分中的数据,或者许多其他可能性。
答案 3 :(得分:1)
data[1][25] = 20; //Should segfault? AAAAA
如果您不被允许访问该位置,则会发生段错误。 C++
中没有检查以查看您访问的位置是否在代码点之前有效。
您获得了一个输出,因为它存储在该位置。它可能是任何东西。这是未定义的行为,每次都可能得不到相同的结果。
请参阅this回答,虽然它讨论了abput局部变量,但它提供了很好的例子,说明这种数据访问如何是未定义的行为
data
和data[0]
都是指针(无论是单引号还是双引脚)。它们具有每个实现的定义大小。在您的情况下,pointer
的大小是计算机上int
大小的两倍。因此,输出。 sizeof
与指向数组的指针一起使用时(而不是数组,即声明为数组char a[]
的数组等)gives the size of the pointer
答案 4 :(得分:0)
数据[0]和数据都是指针。指针在32位系统上的大小为4,在64位系统上为8。因此,m和n相等。 int的大小始终为4.