可以使用memset初始化二维数组吗?



根据C标准(所以链接1和链接2),我们不能使用越界索引访问行中的元素:

int x[10][10] = ...; // initialize x
int q = x[0][10]; // This is an out-of-bounds access

那么使用下面的循环初始化数组是否有效?

int *p = &x[0][0];
for (int i = 0; i < 100; ++i)
p[i] = 0;

如果这是无效的,那么用memset(&x[0][0], 0, sizeof(x))初始化x是有效的吗?

int *p = &x[0][0];
memset(p, 0, sizeof(x))?

编辑:我想知道在c++中答案是否也不同…!:)

该循环无效,请参见@ ericdeferischil的注释。

是的,memset方法也是有效的。但这不是首选的解决方案。它对单个字节进行操作,因此只能合理地用于内存归零。

c++

  • 值初始化T array[10][10] = {};将原语类型的数组归零,为类调用默认构造函数。
  • std::fill(p,p+100,value)用于分配特定的值。没有标准的方法可以将数组初始化为非零值而不列出它们。
  • std::array<T,N>是已知大小数组的首选方式。

C

cppreference

C中没有对应于c++中值初始化的特殊构造;但是,可以使用={0}(或(T){0}在复合字面值中)(从C99开始),因为C标准不允许空结构体、空联合或零长度的数组。

因此,在嵌套数组的情况下,使用T array[10][10] = {{0}};

您在标题中问道:

我可以使用memset初始化一个二维数组吗?

是的,因为memset(...)只关心字节数,你可以这样使用它:

int x[10][10];
memset(&x, 0, sizeof(x));

但是在C++中,一个空的初始化列表也会做同样的事情,如:

int x[10][10] = {};

和在C自C99(如在评论中提到),我们可以这样做,而不是:

int x[10][10] = {{0}};

不管怎样,你说:

int q = x[0][10];//这是一个越界访问

int *p = &x[0][0];
for (int i = 0; i < 100; ++i)
p[i] = 0;

是的,但只是因为你做了一些像设置为0这样简单的事情,更复杂的逻辑可能需要你进行二维循环,比如:

for (int x = 0; x < 10; ++x) {
for (int y = 0; y < 10; ++y) {
myArray[x][y] = something_more_complex_here;
}
}

最新更新