为什么memset()错误地初始化int?

Ahm*_*mad 24 c c++ memset

为什么以下程序的输出84215045

int grid[110];
int main()
{
    memset(grid, 5, 100 * sizeof(int));
    printf("%d", grid[0]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*non 46

memset将目标缓冲区的每个字节设置为指定的值.在您的系统上,一个int是四个字节,每个字节在调用之后为5 memset.因此,grid[0]具有值0x05050505(十六进制),84215045以十进制表示.

有些平台提供了替代API,memset可以将更宽的模式写入目标缓冲区; 例如,在OS X或iOS上,您可以使用:

int pattern = 5;
memset_pattern4(grid, &pattern, sizeof grid);
Run Code Online (Sandbox Code Playgroud)

获得你似乎期望的行为.您定位的平台是什么?

在C++中,您应该使用std::fill_n:

std::fill_n(grid, 100, 5);
Run Code Online (Sandbox Code Playgroud)

  • @Ahmad:没注意到你标记了这个C++; 只需使用`std :: fill`. (2认同)

Jam*_*lis 12

memset(grid, 5, 100 * sizeof(int));
Run Code Online (Sandbox Code Playgroud)

你正在设置400个字节,从开始到(char*)grid结束(char*)grid + (100 * sizeof(int)),到这个值5(这里需要强制转换,因为memset字节为单位进行处理,而指针算术进行处理objects.

84215045十六进制是0x05050505; 因为int(在您的平台/编译器/等)上由四个字节表示,当您打印它时,您得到"四个五".


MSN*_*MSN 8

memset是关于设置字节,而不是值.在C++中设置数组值的众多方法之一是std::fill_n:

std::fill_n(grid, 100, 5);
Run Code Online (Sandbox Code Playgroud)

  • 一个好的编译器会将for循环和`std :: fill_n`转换为使用宽对齐存储(可能是向量)的优化代码序列或已知在目标平台上快速的库调用. (2认同)

Moo*_*uck 6

不要使用memset.

您将[]内存的每个字节设置为值5.每个int长度为4个字节[5][5][5][5],编译器正确解释为5*256*256*256 + 5*256*256 + 5*256 + 5 = 84215045.相反,使用for循环,也不需要sizeof().一般来说,sizeof()意味着你正在以艰难的方式做事.

for(int i=0; i<110; ++i)
    grid[i] = 5;
Run Code Online (Sandbox Code Playgroud)

  • 当然,如果您正在编写C++,那么它应该是一个容器和`std :: fill`. (2认同)