memset() 在 c++ 中的工作原理

How memset() works in c++

本文关键字:工作 c++ memset      更新时间:2023-10-16

我创建了一个布尔 2D 数组并使用了这样的memset

bool chk[3][3];
memset(chk, 1, 9*sizeof(chk[0]));

我使用以下代码块按预期获得输出(每行获得 1 个(

for(int i = 0 ; i < 3; i++){
for(int j = 0; j < 3; j++)
cout<<chk[i][j] <<" ";
cout<<endl;
}

但是当我尝试操作数组时,我得到了意想不到的结果

然后我尝试了

memset(chk, 1, 9*sizeof(chk[0][0]));

这次一切都很好,得到了我预期的结果(经过操纵(

你能帮我指出 memset(( 中到底发生了什么吗?

第一个代码片段中的memset调用有三个问题:

  1. 尺寸计算不正确。您可以使用3*sizeof(chk[0])代替9*sizeof(chk[0])。但实际上你应该只使用sizeof(chk),因为你有一个局部变量,而不是一个指针,就像你使用形式参数一样。

  2. 标准不保证true的内存表示形式为位模式 1 的假设。在实践中,它会成立,但最好直接使用值true而不是不必要的假设。

  3. 在C++只需将变量初始化为零即可使其全部为零,例如bool chk[3][3] = {};,或使用std::fill用给定值填充数组,例如fill( &chk[0][0], &chk[0][0] + 9, true );.


附录:为了迂腐,在第 1 点中假设bool是 1 个字节。这也是一个在实践中成立的假设,但标准并不能保证。令人高兴的是,这不是使用std::fill的问题。

sizeof(chk[0])sizeof(bool[3]),这显然不同于sizeof(chk[0][0])sizeof(bool)

使用memset(chk, 1, 9*sizeof(chk[0]));,您可以超出数组chk的边界进行写入并获得未定义的行为。

让我们来看看std::memset的文档是怎么说的:

如果计数大于 dest 指向的对象的大小,则行为未定义。

在第一个代码中,9*sizeof(chk[0])大于chk的大小,因此程序的行为是不确定的。

memset(chk, 1, sizeof chk)会更简单,就大小而言显然是正确的。

sizeof(array)显然会返回数组的大小(以字节为单位(。在第一种情况下,您提交给运算符的数组是子数组之一。C++中的多维数组不是。它们是数组的一维数组。sizeof(chk)评估完整数组的大小并将其除以sizeof(chk[0][0])以获得元素的数量。不要使用memset因为如果会对布尔值的二进制表示做一些奇怪的事情,请使用std::fill