struct {0}和memset 0之间有什么区别?

13
假设我们有这样的结构体:
struct A
{
    int x;
    int y;
};

什么是两者之间的区别?

A a = {0};

A a;
memset(&a,0,sizeof(A));

1
那么,A a = { 0 }; 能保证将填充位也设置为0吗?如果不能,那也是一个区别。 - user529758
@H2CO3 在C2011中是这样的,在C99中不保证。(但既然是C,那么仍需要写成struct A a = {0}; - Daniel Fischer
@H2CO3,我们在谈论访问其内存区域是未定义行为的情况吗? - John Dvorak
@JanDvorak 是的,我们是。但从技术上讲,无论我们是否想要访问它,它仍然存在差异。 - user529758
如果考虑到可能会影响UD结果的任何因素,那么没有什么是无关紧要的,特别是当它达到编译器时。您无法推理UD-它不必有意义。 - John Dvorak
显示剩余2条评论
2个回答

14

没有。最终的结果是两个成员都被初始化为0

C99标准6.7.8.21:

如果在大括号列表中提供的初始化项数量少于聚合体(数组或结构体)的元素或成员数量,或者用于初始化已知大小的数组的字符串文字中字符数量少于数组中的元素数量,则剩余部分的聚合体将隐式初始化与具有静态存储期的对象相同。

您的结构体A是一个聚合体,并应用上述规则。因此,所有结构成员的值都与具有静态存储期的对象相同,即0

C99标准7.21.6.1 memset函数:

void *memset(void *s, int c, size_t n);

memset函数将c(转换为无符号字符)的值复制到指向s对象的前n个字符中。

简单来说,结构体A中的所有成员(包括对齐/填充位)都设置为0

请注意,C中这两个结构之间的唯一区别是memset还将对齐/填充设置为0,而聚合初始化仅保证结构体成员设置为0

无论哪种情况,您都不能通过常规语言构造访问对齐/填充字节,因此两者均可获得相同的效果。


1
我忘记了这个值,但如果结构体有填充或对齐,这会有影响吗? - Avi Moraly
4
我认为人们应该在提问时尽最小努力。至少要正确地复制和粘贴 - 这并不过分要求。 - Luchian Grigore
4
这并不要求太多,而是对一个声望为“1”的新用户的期望。我认为期望他们采取道义上的优越地位并回答所问的问题并不过分。我甚至会建议修改问题以反映明显之处,并留下关于下次小心的提示。但高声望的用户却通过提供华丽而毫无帮助的答案来赚取声望,这令人失望。 - Alok Save
2
这不是关于占据高地与否,而是推进精炼问题。特别是对于声望仅为1的用户,这是教育。我选择“给你一个回答,如果不符合你想要的,请花时间提出一个好的问题”,而非“让我来为你修复它,不要让它困扰你”。 - Luchian Grigore
2
我从未试图“掩盖”我的“声望收割” - 我已经非常清楚地表明了我这样做,主要是因为没有什么问题。至少我承认了它 - 而你,另一方面,显然认为你不这样做,当事实上回答这些问题就足以证明你在收割声望。如果我想利用这个问题获得投票,我向你保证我也可以编辑并回答原意版本。这不是什么高深的技术。所以,在这种情况下,我确实想推动更清洁的问题。在这种情况下,不是我在收割声望。 ;) - Luchian Grigore
显示剩余7条评论

6

两者都是将内存设置为0

第一个用于将静态分配的内存设置为0

A a ={0}; // set a staic memory to 0

你不能用这种方式实现:

而你不能用以下方式:

A *a = malloc(sizeof(A)); a = {0} // This could not be done

第二个用于将动态和静态分配的内存都设置为0。
A a;
memset(&a,0,sizeof(A));

而且你也可以这样做
A *a = malloc(sizeof(A)); memset(a,0,sizeof(A));

另一件事情

使用 memset 将内存设置为 0 时,你在调用一个函数(这需要时间)。而使用 {0} 进行设置时,并不会调用函数。因此,{0} 可能比 memset 更快。


OP在询问他引用的示例代码的具体区别。虽然答案中提到的差异是有效且重要的,但并没有真正回答OP的问题。 - Alok Save
1
他的问题标题比较笼统,因此这个答案可以回答这个标题问题。 - MOHAMED
1
你错误地使用了“static”这个术语。在C语言中,“static”描述的是一种存储类。你也可以将非静态(即自动)结构体设置为零。 - Jens
1
关于无法设置动态分配的观点是100%不正确的。在您的第二个示例中,您只需使用*a = (A){0}即可。 - Craig Barnes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接