为什么memset()不正确地初始化int?

为什么下面的程序84215045的输出?

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

memset将目标缓冲区的每个字节设置为指定的值。 在你的系统上,一个int是四个字节,在调用memset之后每个字节都是五个字节。 因此, grid[0]的值为0x05050505 (hex),十进制为84215045

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

 int pattern = 5; memset_pattern4(grid, &pattern, sizeof grid); 

得到你期待的行为。 你的目标是什么平台?

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

 std::fill_n(grid, 100, 5); 
 memset(grid, 5, 100 * sizeof(int)); 

您将设置400个字节,以(char*)grid开始,以(char*)grid + (100 * sizeof(int)) ,值为5 (因为memset字节为单位进行处理 ,交易objects

在hex中的0x050505050x05050505 ; 因为int (在你的平台/编译器/等)由四个字节表示,所以当你打印它时,你会得到“四五”。

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

 std::fill_n(grid, 100, 5); 

不要使用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; 

那么, memset用选定的值写入字节。 因此int将看起来像这样:

 00000101 00000101 00000101 00000101 

然后解释为84215045。

你实际上并没有说你想要你的程序做什么。

假设你想将grid的前100个元素设置为5(并忽略100110差异),只需执行以下操作:

 for (int i = 0; i < 100; i ++) { grid[i] = 5; } 

我知道你对速度很关心,但你的担心可能是错误的。 一方面, memset()很可能被优化,因此比简单的循环更快。 另一方面,优化可能包括一次写入多个字节,这就是这个循环所做的。 另一方面, memset()无论如何都是一个循环; 明确写入循环而不是将其隐藏在函数调用中不会改变这一点。 另一方面,即使循环很慢,也不太可能; 集中精力编写清晰的代码,并考虑优化它, 如果实际测量结果表明存在显着的性能问题。

你花了很多数量级的时间来写这个问题,而不是你的计算机花费的时间来设置grid

最后,在我用完手之前(太迟了!), memset()是不是有多快,如果它不做你想要的。 (根本不设置grid更快!)

由于memset写入字节,我通常使用它来设置一个int数组为零:

 int a[100]; memset(a,0,sizeof(a)); 

或者你可以使用它来设置一个字符数组,因为一个字符恰好是一个字节:

 char a[100]; memset(a,'*',sizeof(a)); 

更重要的是,int数组也可以通过memset设置为-1:

 memset(a,-1,sizeof(a)); 

这是因为在int中-1是0xffffffff,在char(一个字节)中是0xff。

此代码已经过testing。 这是将“整数”数组的值设置为0到255之间的一种方法。

 MinColCost=new unsigned char[(Len+1) * sizeof(int)]; memset(MinColCost,0x5,(Len+1)*sizeof(int)); memset(MinColCost,0xff,(Len+1)*sizeof(int));