memset() 在 c++ 中的工作原理
How memset() works in c++
我创建了一个布尔 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
调用有三个问题:
-
尺寸计算不正确。您可以使用
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(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
。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 为什么stream::忽略未按预期工作