假设我有一个这样的数组:
string x[2][55];
如果我想用“-1”填充它,这是正确的方法:
fill(&x[0][0],&x[2][55],"-1");
当我试图运行它时崩溃了。如果我将x [2] [55]更改为x [1] [54]它可以工作,但它不会初始化数组的最后一个元素。
这是一个证明我的观点的例子:
string x[2][55];
x[1][54] = "x";
fill(&x[0][0],&x[1][54],"-1");
cout<<x[1][54]<<endl; // this print's "x"
答案 0 :(得分:3)
因为当你有一个多维数组时,超出第一个元素的地址有点令人困惑。答案很简单:
&x[1][55]
让我们考虑一下2d数组x[N][M]
在内存中的布局
[0][0] [0][1] ... [0][M-1] [1][0] [1][1] ... [1][M-1] [N-1][0] .. [N-1][M-1]
因此,最后一个元素是[N-1][M-1]
,超出的第一个元素是[N-1][M]
。如果你取[N][M]
的地址,那么你会走到尽头,你会覆盖很多内存。
计算超出结束的第一个地址的另一种方法是使用sizeof。
&x[0][0] + sizeof(x) / sizeof(std::string);
答案 1 :(得分:0)
从正式和迂腐的角度来看,这是非法的。将二维数组重新解释为一维数组会导致未定义的行为,因为您确实试图访问超出其边界的1D x[0]
数组。
在实践中,这将起作用(尽管一些代码分析工具可能会将此报告视为违规)。但是为了正确指定“超越最后一个元素”的指针,你必须要小心。它可以指定为&x[1][55]
或&x[2][0]
(两者都是相同的地址)。