简体   繁体   English

memset()如何在C ++中工作

[英]How memset() works in c++

I created a boolean 2D array and used memset like this : 我创建了一个布尔2D数组并像这样使用memset

bool chk[3][3];

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

I got output as expected using the following blocks of code (got 1 in every row ) 我使用以下代码块获得了预期的输出(每行1个)

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

but when I tried to manipulate the array I got unexpected result 但是当我尝试操纵数组时,得到了意外的结果

and then I tried with 然后我尝试了

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

and this time everything was fine and got my expected result(after manipulation) 这次一切都很好,并得到了我预期的结果(经过操作)

Can you please help me pointing out what exactly happened in memset() ? 您能帮我指出一下memset()中到底发生了什么吗?

The memset call in your first code snippet has three problems: 第一个代码段中的memset调用存在三个问题:

  1. The size calculation is incorrect. 尺寸计算不正确。 Instead of 9*sizeof(chk[0]) you could use 3*sizeof(chk[0]) . 可以使用3*sizeof(chk[0])代替9*sizeof(chk[0]) 3*sizeof(chk[0]) But really you should just use sizeof(chk) , because you have a local variable, not a pointer, as you would have with a formal argument. 但是实际上您应该只使用sizeof(chk) ,因为您有一个局部变量,而不是指针(如形式参数一样)。

  2. The assumption that memory representation of true is bitpattern 1, is not guaranteed by the standard. 标准不保证内存表示为true的假设是位模式1。 In practice it will hold, but it would be far better to use the value true directly instead of a needless assumption. 实际上,它会成立,但是最好直接使用true而不是不必要的假设。

  3. In C++ simply zero-initialize the variable to make it all zeroes, eg bool chk[3][3] = {}; 在C ++中,只需将变量初始化为零即可使其全部为零,例如bool chk[3][3] = {}; , or use std::fill to fill an array with a given value, eg fill( &chk[0][0], &chk[0][0] + 9, true ); ,或使用std::fill用给定值填充数组,例如fill( &chk[0][0], &chk[0][0] + 9, true ); .


Addendum: to be pedantic, in point 1 there is an assumption that a bool is 1 byte. 附录:要学究,在第1点中,假设bool为1字节。 That's also an assumption that holds in practice but is not guaranteed by the standard. 这也是一个在实践中成立的假设,但标准并不能保证。 Happily it's not an issue for use of std::fill . 幸运的是,使用std::fill并不是问题。

sizeof(chk[0]) is sizeof(bool[3]) which is obviously different from sizeof(chk[0][0]) which is sizeof(bool) . sizeof(chk[0])sizeof(bool[3]) ,这明显不同于sizeof(chk[0][0])这是sizeof(bool)

With memset(chk, 1, 9*sizeof(chk[0])); 使用memset(chk, 1, 9*sizeof(chk[0])); you write beyond the bounds of the array chk and get undefined behaviour. 您编写超出数组chk的边界并获得未定义的行为。

Let's take a look at what the documentation of std::memset says: 让我们看看std::memset的文档怎么说:

If count is greater than the size of the object pointed to by dest, the behavior is undefined. 如果count大于dest指向的对象的大小,则该行为未定义。

In the first code, 9*sizeof(chk[0]) is greater than the size of chk , and therefore the behaviour of the program is undefined. 在第一个代码中, 9*sizeof(chk[0])大于chk的大小,因此程序的行为是不确定的。

memset(chk, 1, sizeof chk) would be simpler, and obviously correct as far as the size is concerned. memset(chk, 1, sizeof chk)会更简单,并且就大小而言显然是正确的。

sizeof(array) obviously would return size of array in bytes. sizeof(array)显然会返回以字节为单位的数组大小。 In first case the array you submitted to the operator is one of sub-arrays. 在第一种情况下,您提交给运算符的数组是子数组之一。 Multidimensional arrays in C++ aren't. C ++中的多维数组不是。 They are single-dimensional arrays of arrays. 它们是数组的一维数组。 Do sizeof(chk) to evaluate size of full array and divide it by sizeof(chk[0][0]) to get amount of elements. 执行sizeof(chk)评估整个数组的大小,然后将其除以sizeof(chk[0][0])即可获得元素数量。 Don't use memset because if would do some strange thing to binary representation of bool, use std::fill . 不要使用memset因为如果要对bool的二进制表示形式做一些奇怪的事情,请使用std::fill

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM