C++ 关于C+中stl填充函数的问题+;

C++ 关于C+中stl填充函数的问题+;,c++,stl,C++,Stl,假设我有这样一个数组: 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"); c

假设我有这样一个数组:

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"
字符串x[2][55];
x[1][54]=“x”;
填写(&x[0][0],&x[1][54],“-1”);

cout因为当您使用多维数组时,第一个元素之外的地址计算起来有点混乱。答案很简单,你可以这样做:

&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);

从正式和迂腐的角度来看,这是非法的。将二维数组重新解释为一维数组会导致未定义的行为,因为您实际上是在试图访问超出其边界的一维
x[0]
数组


在实践中,这是可行的(尽管一些代码分析工具可能会将此报告视为违规)。但是为了正确地指定指向“超出最后一个元素”的指针,您必须小心。它可以指定为
&x[1][55]
&x[2][0]
(两者都是相同的地址)。

aaaaah,fill填充间隔[first,last]-首先关闭,最后打开,所以“last”它本身刚好超出了最后一个填充的元素。我明白了。@AndreyT-你确定吗?我读到C++03规范8.3.4.7、.8和.9要求多维数组按行顺序连续放入内存。@R Samuel Klatchko:这已经讨论过很多次了。是的,它需要以这种方式放入内存。然而,指针算术规则请明确说明,如果您有一个类型为
string*
的指针指向1D数组
x[0]
的元素,则不允许您使用指针算法跨越1D数组
x[0]
的边界。如果编译器选择使用“编译器魔法”强制执行此操作我认为C和C++中的多维数组被打破,超出了修复的所有希望。