gcc 4.4.4 C89
我只是想知道大多数C程序员在想要将内存归零时做了什么.
例如,我有一个1024字节的缓冲区.有时我会这样做:
char buffer[1024] = {0};
这将使所有字节为零.
但是,我应该这样声明并使用memset吗?
char buffer[1024];
.
.
memset(buffer, 0, sizeof(buffer));
有没有真正的理由你必须将记忆归零?不做的最坏情况是什么?
JSB*_*ոգչ 12
我非常喜欢
char buffer[1024] = { 0 };
它更短,更易于阅读,并且更不容易出错.仅用于memset动态分配的缓冲区,然后更喜欢calloc.
Tim*_*ost 12
可能发生的最坏情况?您最终(不知不觉地)使用非NULL终止的字符串,或者在打印到缓冲区的一部分后继承其右侧的任何内容的整数.然而,即使您初始化缓冲区,未终止的字符串也可能以其他方式发生.
编辑(来自评论)世界末日也是一个遥远的可能性,取决于你在做什么.
两者都是不可取的.但是,除非完全避开动态分配的内存,否则大多数静态分配的缓冲区通常都很小,这使得memset()相对便宜.事实上,比大多数calloc()动态块的要求便宜得多,动态块往往大于~2k.
c99包含有关默认初始化值的语言,但我似乎不能gcc -std=c99同意这一点,使用任何类型的存储.
尽管如此,由于许多较旧的编译器(以及不完全是c99的编译器)仍在使用中,我更愿意使用它 memset()
spo*_*son 10
在char buffer[1024]没有初始化的情况下定义时,您将获得未定义的数据.例如,调试模式下的Visual C++将使用0xcd初始化.在发布模式下,它将简单地分配内存,而不关心以前使用该块中发生的情况.
此外,您的示例演示了运行时与编译时初始化.如果您char buffer[1024] = { 0 }是全局或静态声明,它将使用其初始化数据存储在二进制数据段中,从而将二进制大小增加大约1024个字节(在本例中).如果定义在函数中,则它存储在堆栈中并在运行时分配,而不是存储在二进制文件中.如果在这种情况下提供初始化程序,则初始化程序存储在二进制文件中,并且在运行时memcpy()初始化buffer时执行等效的初始化程序.
希望这有助于您确定哪种方法最适合您.
在这种特殊情况下,没有太大区别.我喜欢= { 0 }过memset,因为memset是更容易出错:
memset(例如memset(buf, sizeof buf, 0)代替memset(buf, 0, sizeof buf).一般来说,= { 0 }也可以更好地初始化structs.它有效地初始化所有成员,就好像你已经编写= 0初始化每个成员一样.这意味着保证指针成员被初始化为空指针(可能不是全位 - 零,并且如果您使用过,则所有位为零memset).
另一方面,= { 0 }可以将填充位struct留作垃圾,因此如果您打算memcmp稍后用它来比较它们可能不合适.