0

我开始学习 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。难道我做错了什么?

4

5 回答 5

3

C++ 不对数组进行边界检查。访问数组边界之外的数据是未定义的行为,任何事情都可能发生。它可能会导致段错误,但可能不会。如果您在数组之前或之后有有效的内存区域,您最终可以访问或修改该内存。这可能会导致程序使用的其他数据损坏。

你使用的sizeof也是不正确的。sizeof是一个编译时构造。它不能用于在运行时通过指针值确定数组的大小。如果您需要这种类型的功能,请使用std::arraystd::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].
于 2013-06-24T14:11:34.367 回答
2

在 AAAA,您有未定义的行为。从那时起,任何事情都可能发生——甚至更有趣,甚至更早。

在标准 C++ 中没有“段错误”这样的行为。并且实现可以定义一些操作来做到这一点,但我不知道是否有任何打扰。在某些情况下,它只是偶然发生的。

于 2013-06-24T14:07:05.960 回答
1

访问其边界之外的数组是未定义的行为。所以没有理由期望会发生什么特别的事情:它可能会崩溃、返回正确的答案、返回错误的答案、在程序的另一部分默默地破坏数据,或者一大堆其他可能性。

于 2013-06-24T14:08:37.217 回答
1
data[1][25] = 20; //Should segfault? AAAAA

如果不允许您访问该位置,则会出现段错误。没有检查C++您正在访问的位置是否有效,从代码角度来看

您获得了一个输出,因为它存储在该位置。它可能是任何东西。这是未定义的行为,您可能不会每次都得到相同的结果。

看到这个答案,虽然它谈论 abput local variables ,但它提供了很好的例子来说明这种数据访问如何可能是未定义的行为

data并且data[0]都是指针(单或双无关紧要)。它们为每个实现定义了大小。在您的情况下,大小是您机器上pointer大小的两倍。int因此,输出。 sizeof当与指向数组的指针(而不是数组,即声明为数组的数组char a[]等)一起使用时,会给出指针的大小

于 2013-06-24T14:16:02.337 回答
0

data[0] 和 data 都是指针。指针大小在 32 位系统上为 4,在 64 位系统上为 8。因此,m 和 n 相等。int 的大小始终为 4。

于 2013-06-24T14:15:48.027 回答