为什么一个二维阵列会导致赛段故障,而另一个则不会导致?



有几种方法可以定义二维数组。

我发现在使用以下代码定义数组时:

int arr[2][2];
cout << arr[3][3];

这不会导致赛格错误。这只是打印一些虚拟值。

另一方面

int** arr = new int*[2];
for(int i = 0; i < 2; i++) arr[i] = new int[2];
cout << arr[3][3];

这会导致赛段错误。

这两者之间有什么区别?

读取未初始化的值是未定义的行为。您的程序无效(两种变体(,并且当您这样做并且允许任何行为时没有任何意义。编译器实际上被允许做任何事情。您无法推理包含UB的程序,甚至不要尝试。

静态数组位于堆栈中,因此它不会发生段错误,因为程序可以访问自己的堆栈。但是,如果超出堆栈范围,则可以对静态数组进行分段错误。

另一方面,动态数组(指针(位于堆中。因此,通过超出范围,您要求在程序的专用内存放置之外获取指针,从而导致段错误。

这称为未定义行为。

你有未定义的行为。任何事情都可能发生。推测为什么你会得到这些结果是没有用的。

也就是说,这可能是正在发生的事情:

第一个是堆栈上的连续内存块(2*2*sizeof(int((,其中arr[3][3]表示在该块开始后从 3*3*sizeof(int( 字节读取数据。

另一个是堆上的一个内存块(2*sizeof(int*((,包含两个指针指向堆上的两个单独的内存块(每个 2*sizeof(int((,其中arr[3][3]表示从第一个内存块之后的 3*sizeof(int*( 字节读取数据,将您在那里找到的任何内容解释为内存地址, 然后从该地址后的 3*sizeof(int( 字节读取数据。

相关内容

  • 没有找到相关文章

最新更新