【问题标题】: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 char 和 unsigned 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 相同,但不能保证。这取决于硬件架构+操作系统+编译器。
您的问题的简短回答是:否。