【问题标题】:memset an array of void pointers [duplicate]memset一个空指针数组[重复]
【发布时间】:2015-03-24 07:59:33
【问题描述】:

考虑以下对void 指针数组的初始化:

#include <string.h>

void foo()
{
    void * a[10];
    memset(a, 0, sizeof a);
    // ...
}

memset 调用之后,数组是否保证保存 NULL 指针?

【问题讨论】:

  • (回答后发现骗子)。

标签: c arrays pointers null memset


【解决方案1】:

不,不能保证。将 0 转换为指针类型被定义为产生一个空指针 [6.3.2.3.3],但在这里您将指针的对象表示设置为全零字节。标准没有指定指针的对象表示,所以一个全零字节的指针或者可能不是一个空指针。

我认为您的问题不需要提及数组,因为询问 p 现在是否为空指针取决于同一问题:

void *p;
memset(&p, 0, sizeof p);

【讨论】:

    【解决方案2】:

    没有。根据C11 6.3.2.3 Pointers /3,整数常量或零表达式将转换为空指针。但是,类型的底层表示6.2.6 指定,其中/1 声明:

    所有类型的表示均未指定,除非本小节中另有说明。

    鉴于该部分中没有与指针有关的内容,因此您不能假设空指针全为零,这就是您从 memset() 调用中得到的(signed charunsigned char 都不允许填充位和正零在所有可能的编码中都以相同的方式表示)。

    更安全的方法是:

    void foo (void) {
        void *a[10];
        for (size_t s = 0; s < sizeof(a) / sizeof(*a); s++)
            a[s] = 0;
    }
    

    您可以使用 memset,如果您知道全零位是您的实现中空指针的正确底层表示,但它不会是可移植的。考虑到不使用该表示的活跃使用的机器数量(如果有的话,非常少),这可能不是问题。请注意可能的后果。

    【讨论】:

      【解决方案3】:

      如果您将NULLs 放入其中,那么是的,它将保存NULLs。

      但你用零填充它,0 可能会发生NULL 相同,但不能保证。这取决于硬件架构+操作系统+编译器。

      您的问题的简短回答是:

      【讨论】:

        猜你喜欢
        • 2012-10-02
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        • 2012-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多