memset 或 bzero 是不是保证结构中的字段指针将被清空?

Posted

技术标签:

【中文标题】memset 或 bzero 是不是保证结构中的字段指针将被清空?【英文标题】:do memset or bzero guarantee that a field pointer in a struct will be nulled out?memset 或 bzero 是否保证结构中的字段指针将被清空? 【发布时间】:2012-11-02 00:29:29 【问题描述】:

假设你有一个 C++ 类 Foo,你说:

Foo* foos = new Foo[SOME_CONSTANT];
memset(foos, 0, sizeof(Foo)*SOME_CONSTANT);
//or the bzero equivalent

并且 Foo 有一个数据成员 Bar* barPtr。以上操作能否保证 barPtr 将是 NULL 吗? (即零)。我在 gdb 中遇到了一个案例,这不适用于 memset,我很好奇为什么。

我知道上述做法可能是不好的做法,但我是出于好奇。

我意识到我有一个额外的 ,我在 memset 中执行 sizeof(Foo)*SOME_CONSTANT...

【问题讨论】:

您的问题似乎有些混乱。 memset 应确保 barPtr 设置为零,这不一定是 NULL。你认为barPtr 有什么价值? memset() 会将目标设置为全位为零。这通常会将指针设置为 null,但该语言不需要将 null 指针表示为全位为零。但是我对您的“gdb 中这不适用于 memset 的情况”感到惊讶;我不知道有任何支持 gdb 的系统,其中空指针 不是 全位为零。 【参考方案1】:

一方面,它是实现定义的。 memsetbzero 将使用全零位模式填充指针值,这不能保证是给定平台上空指针的物理表示。它甚至不能保证产生一个有效的指针值,这意味着您最终可能会得到所谓的 trap 表示,这会在访问时触发未定义的行为。

另一方面,bzero 是(或曾经是)POSIX 规范的一部分。如果内存服务,POSIX 要求(或至少曾经要求)空指针由全零位模式表示,这意味着在 POSIX 系统上它确实会将指针设置为空。

但是,POSIX 提供的保证只是我的答案第一部分中提到的特定于实现的属性的一个示例。语言(C 或 C++)不提供此类保证。

【讨论】:

【参考方案2】:

没有。空指针的表示不需要全部为零。

参见comp.lang.c FAQ 的section 5 和question 7.31。

【讨论】:

@James,我认为是。请参阅我添加到答案中的常见问题解答。 @aleguna,不,不是。请参阅常见问题解答。如果p 是指针,则写入p=0 不会将p 的所有位设置为零。 问题不是关于 NULL,他在问为什么他的 memset 调用没有将类成员归零 @lhf,问题的第一行说的是class @aleguna: NULL 在 C 中可以定义为 constant 整数零,而不仅仅是任何零。 IE。这样的NULL 必须是编译时零,编译器可以立即识别为零。这种零本身是“所有位为零”还是完全不相关,因为一旦将其转换为指针类型,它的表示就可以完全改变。同时,如果 C 中的 NULL 被定义为 (void *) 0,您就不能再声称它是“所有位为零”。 (void *) 0 可以很容易地代表0xBAADFOOD

以上是关于memset 或 bzero 是不是保证结构中的字段指针将被清空?的主要内容,如果未能解决你的问题,请参考以下文章

bzero, memset ,setmem 区别

为啥在 memset 中使用 '\0' 而不是 0?

函数--c

bzero - 向字符串写入零

关于memset()

memset 中的第一个参数传递数组或指针