无法解释以下C ++代码段的输出

时间:2018-07-12 09:21:21

标签: c++ multidimensional-array output memset

#include <bits/stdc++.h>
using namespace std;

int main() {
   int dp[5][6];
   memset(dp,0,sizeof(dp));
   dp[1][0]=0;
   for(int i=1;i<=9;i++){
      dp[1][i]=1;
   }
   cout<<dp[2][0]<<endl;
   cout<<dp[3][0]<<endl;
 }

上面的代码片段产生了意外的输出:

1
0

但是,当我将dp数组的大小更改为dp [100] [100]时, 我得到的预期输出为:

0
0

我也尝试打印2D矩阵大小:

sizeof(dp)/sizeof(int)

我得到正确的值:如果是dp [5] [6],则为30;如果是dp [100] [100],则为10000。 我在Linux中使用标准的g ++编译器编译并执行了代码。 有人可以向我解释这种错误输出的原因。

4 个答案:

答案 0 :(得分:2)

阵列的尺寸为[5][6]。因此,当您尝试使用dp[1][i] = 1i的{​​{1}}进行1时,9会完成。由于“行”中的元素数为dp[1][6] = 1,它的操作与6相同,因为该二维数组的所有元素都按顺序存储。

因此,基本上,当您尝试访问dp[2][0] = 1时,就像dp[1][i]。并且startOffset + 1 * rowSize + i大于行大小。

答案 1 :(得分:0)

首先,这不是很好的代码样式,但是由于我不确定您要实现的目标,因此我不建议如何改进它,而只是回答您的问题:解释输出。

在第一种情况下

int main() {
   int dp[5][6];
   memset(dp,0,sizeof(dp));
   dp[1][0]=0;
   for(int i=1;i<=9;i++){
      dp[1][i]=1;
   }
   cout<<dp[2][0]<<endl;
   cout<<dp[3][0]<<endl;
 }

dp的第二个索引的范围是05(因为您声明了int dp[5][6]并且C ++数组是从零开始的)。但是,然后将第二个索引(在i循环中的for循环中,从19。因此,索引6, 7, 8, 9超出范围,通常这会使您的程序崩溃。

它不会崩溃,因为您已经声明了2d数组,该数组分配在单个连续的内存块中,因此dp[1][6]溢出到2d数组的下一部分。即dp[1][6]等同于dp[2][0]

这就是为什么在第一种情况下,您发现dp[2][0]等于1

但是,当您将声明更改为dp[100][100]时,6, 7, ...是有效的第二个索引,因此它永远不会溢出,并且dp[2][0]保持其初始化值0

答案 2 :(得分:0)

首先要提到的是dp [5] [6]是2D数组,其中有5行,每行有6列。您可以将其可视化为网格。但是现实是每一行都是一个接一个地顺序排列的。第一行可以容纳0到5。现在在循环中分配dp [1] [6] = 1时,这意味着dp [2] [0]被分配了1,因为dp [1] [5]是最后一个元素第一行的第一行和第六元素是第二行的第一元素。对于dp [2] [1],dp [2] [2]和dp [2] [3],您将获得相同的ans。但是在dp [2] [4]处将为0。

要提到的一件事是,在不同的体系结构中它可能有所不同。同样,不同的编译器可以以不同的方式工作。

答案 3 :(得分:0)

请注意,在C ++中,使用memset对数组进行零初始化是较差的做法。最佳做法是使用aggregate initializer syntax

int dp[5][6] = {}; // Zero-initialize.