memset() 在 C++ 中的工作原理
How memset() works in c++
我创建了一个布尔二维数组并像这样使用 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() 到底发生了什么吗?
sizeof(chk[0])
是 sizeof(bool[3])
这明显不同于 sizeof(chk[0][0])
是 sizeof(bool)
.
使用 memset(chk, 1, 9*sizeof(chk[0]));
时,您的写入超出了数组的范围 chk
并得到了未定义的行为。
我们来看看std::memset
的文档是怎么说的:
If count is greater than the size of the object pointed to by dest, the behavior is undefined.
在第一个代码中,9*sizeof(chk[0])
大于 chk
的大小,因此程序的行为未定义。
memset(chk, 1, sizeof chk)
会更简单,而且就大小而言显然是正确的。
您的第一个代码片段中的 memset
调用存在三个问题:
大小计算不正确。您可以使用 3*sizeof(chk[0])
而不是 9*sizeof(chk[0])
。但实际上你应该只使用 sizeof(chk)
,因为你有一个局部变量,而不是指针,就像你在正式参数中那样。
true
的内存表示是位模式 1 的假设不受标准保证。在实践中它会成立,但最好直接使用值 true
而不是不必要的假设。
在 C++ 中,简单地对变量进行零初始化以使其全为零,例如bool chk[3][3] = {};
,或使用 std::fill
用给定值填充数组,例如fill( &chk[0][0], &chk[0][0] + 9, true );
.
附录:为了迂腐,在第 1 点中假设 bool
是 1 个字节。这也是一个在实践中成立但不受标准保证的假设。令人高兴的是,使用 std::fill
.
不是问题
sizeof(array)
显然 return 数组的字节大小。在第一种情况下,您提交给操作员的数组是子数组之一。 C++ 中的多维数组不是。它们是数组的一维数组。做 sizeof(chk)
来评估完整数组的大小并将其除以 sizeof(chk[0][0])
以获得元素的数量。不要使用 memset
因为如果会对 bool 的二进制表示做一些奇怪的事情,请使用 std::fill
.
我创建了一个布尔二维数组并像这样使用 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() 到底发生了什么吗?
sizeof(chk[0])
是 sizeof(bool[3])
这明显不同于 sizeof(chk[0][0])
是 sizeof(bool)
.
使用 memset(chk, 1, 9*sizeof(chk[0]));
时,您的写入超出了数组的范围 chk
并得到了未定义的行为。
我们来看看std::memset
的文档是怎么说的:
If count is greater than the size of the object pointed to by dest, the behavior is undefined.
在第一个代码中,9*sizeof(chk[0])
大于 chk
的大小,因此程序的行为未定义。
memset(chk, 1, sizeof chk)
会更简单,而且就大小而言显然是正确的。
您的第一个代码片段中的 memset
调用存在三个问题:
大小计算不正确。您可以使用
3*sizeof(chk[0])
而不是9*sizeof(chk[0])
。但实际上你应该只使用sizeof(chk)
,因为你有一个局部变量,而不是指针,就像你在正式参数中那样。true
的内存表示是位模式 1 的假设不受标准保证。在实践中它会成立,但最好直接使用值true
而不是不必要的假设。在 C++ 中,简单地对变量进行零初始化以使其全为零,例如
bool chk[3][3] = {};
,或使用std::fill
用给定值填充数组,例如fill( &chk[0][0], &chk[0][0] + 9, true );
.
附录:为了迂腐,在第 1 点中假设 bool
是 1 个字节。这也是一个在实践中成立但不受标准保证的假设。令人高兴的是,使用 std::fill
.
sizeof(array)
显然 return 数组的字节大小。在第一种情况下,您提交给操作员的数组是子数组之一。 C++ 中的多维数组不是。它们是数组的一维数组。做 sizeof(chk)
来评估完整数组的大小并将其除以 sizeof(chk[0][0])
以获得元素的数量。不要使用 memset
因为如果会对 bool 的二进制表示做一些奇怪的事情,请使用 std::fill
.