2013-05-13 75 views
2

在遍历维基百科跟随某些链接时,我偶然发现the following code example,它将char缓冲区初始化为0,但在使用前将memset设置为0。这是必要的吗?如果是这样,为什么?我问的原因是我不是专家,并且示例清楚地表明,这是编码员的意图,在memset上的评论“/* Really initialized to zeroes */”,而不是在初始化上的“/* initialized to zeroes */”。memsetting初始化缓冲区的原因是什么

编辑:请注意,我回滚了导致此问题的维基百科页面上的编辑,因此它在链接中不再可见。

+0

重要的是,在分配的内存部分中存储用于先前计算的清理“垃圾” – 2013-05-13 18:00:33

+0

您会在两个方向看到示例 - 代码无法正确确保缓冲区已初始化,但由于某种形式而未遇到问题幸运的是(我称之为测试没有剔除bug的运气不好)。另一方面,我经常看到如下代码:memset(buffer,0,sizeof(buffer)); snprintf(buffer,sizeof(buffer),“foo is%d”,foo);'清除缓冲区isn'因为它总是会得到一个格式良好的以空字符结尾的字符串。但我猜,安全性比抱歉要好。 – 2013-05-13 18:56:34

回答

10
char buffer[5] = {0}; /* initialized to zeroes */ 

/* some declaration/statements, but no access to buffer object */ 

memset (buffer, 0, sizeof buffer); /* Really initialized to zeroes */ 

在上面的代码中,调用memset是完全没用的。 buffer已保证初始化为0

+0

优秀,谢谢。不要盲目信任维基百科的另一个原因,我想 – 2013-05-13 18:01:08

+2

我没有看到任何方式可以有任何区别的初始化与'{0}'和初始化与'memset()'为'char'数组,但是,对于其他类型,在外部系统上可以有一个,其中0.0不是用全零位表示,通过在指针上下文中写入'0'得到的空指针不是用全零位表示,... – 2013-05-13 18:19:37

+0

@PascalCuoq,用于'struct'类型,'memset'也可以保证填充被清零。 – 2013-05-13 19:45:02

2

跟随ouah的答案。如果你有

char buffer[5] = { 0 } ; 

int main(int argc, char **argv) 
{ 
    memset (buffer, 0, sizeof buffer); 
    ... 

有可能是一个例外:如果你真的做低级别的C编程(不带操作系统)和你的C程序直接调用时没有一个完全的工作环境,那么buffer阵列可能在这种情况下不能正确初始化,因为必需的初始化代码(在main之前运行的代码)缺失。

在这种情况下,这是另一种方式:初始化是无用的(因为它在这个特定的环境中不起作用)并且memset是必要的。

但正如我所说:这实际上只发生在极低级别的C编程中,实际上是环境中的一个错误,它为您提供了非C符合环境。

+0

感谢您的洞察力 - 尽管我意识到不符合标准的C语言环境,但我没有意识到存在一些无法完成明确要求的问题。 – 2013-05-13 20:23:55

+1

我认为这个答案接近有害的FUD。大约十年前,每个人都对C实现的多样性持不同看法,并且你经常发现hack对于从未存在过的或者早已过时的实现来说是“可移植的”,并且即使它们确实存在,它也不会是C实现(而是一种丑陋的C语言)。带回这种怀疑不是**进步。除非你知道没有正确初始化对象的*特定*有趣的目标,否则这样的猜测是没有用的。 – 2013-05-13 21:45:50

+1

@R ..那么:如果你需要用C语言编写一部分引导加载程序(就像我不久前),你真的应该知道我上面写的是什么。这肯定是不是** FUD,如果你必须写在这么低的水平上,你通常会编写你自己的链接器脚本,这反过来可能意味着你根本没有任何“标准”初始化代码... – 2013-05-14 03:31:33