【问题标题】:what is the difference between struct {0} and memset 0 [duplicate]struct {0} 和 memset 0 有什么区别 [重复]
【发布时间】:2012-12-25 15:02:18
【问题描述】:

假设我们有这样的结构:

struct A
{
    int x;
    int y;
};

有什么区别

A a = {0};

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

【问题讨论】:

  • 那么,A a = { 0 }; 是否也保证将填充设置为 0?因为如果不是,那也有区别。
  • @H2CO3 在 C2011 中是这样,在 C99 中不保证。 (但它是 C,所以无论如何它必须是 struct A a = {0};。)
  • @H2CO3 我们是在谈论未定义行为访问的内存区域吗?
  • @JanDvorak 是的,我们是。但从技术上讲,它仍然是一个区别,我们是否想访问它。
  • @H2CO3 如果要考虑可能影响 UD 结果的任何事情,那么没有什么是无关紧要的,尤其是当它到达编译器时。您无法对 UD 进行推理 - 它不必有意义。

标签: c struct


【解决方案1】:

没有。最终结果是两者都将结构成员初始化为0

C99 标准 6.7.8.21

如果大括号括起来的列表中的初始化程序少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则剩余的聚合应隐式初始化,与具有静态存储持续时间的对象相同。

您的结构A 是一个聚合,上面的规则适用于它。因此,所有结构成员都使用与静态存储持续时间相同的值进行初始化。这是0

C99 Standard 7.21.6.1 memset函数:

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

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

简而言之,结构对象A 中的所有成员(包括对齐/填充位)都设置为0

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

在任何一种情况下,您都无法通过约定语言结构访问对齐/填充字节,因此两者都可以获得相同的效果。

【讨论】:

  • 我忘记了这个值,但是如果结构有填充还是对齐,这有关系吗?
  • 我说现在是人们在他们的问题上投入最少精力的时候了。至少正确地复制粘贴 - 要求不高。
  • @LuchianGrigore:要求不高,而是希望新用户拥有代表1。我认为期望占据道德制高点并回答所问的问题并不过分。我想说甚至可以编辑 Q 以反映明显的 & 留下关于下次小心的 OP 注释。令人失望的是,高代表用户通过抛出浮华的起泡答案来兑现代表,这并没有真正帮助 OP 或对任何人都没有帮助,这令人失望。
  • 这不是要不要占领制高点,而是要推动一个干净的问题。 特别是对于有 1 个代表的用户。是教育。我选择“这里是您问题的答案,如果不是您想要的,请花时间提出一个好问题”,而不是“在这里,让我为您解决这个问题,不要让它打扰您”。跨度>
  • 我从来没有试图“掩盖”我的“卖淫”——我已经明确表示我这样做了,主要是因为它没有任何问题。至少我承认——另一方面,你显然认为你不这样做,而仅仅回答这样的问题就足以证明你这样做了。如果我想为投票的问题挤奶,我向你保证,我也可以编辑并回答预期的版本。这不是火箭科学。所以是的,在这种情况下,我确实想提出一个更清晰的问题。在这种情况下,不是我代表嫖娼。 ;)
【解决方案2】:

两者都将内存设置为 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 的 Q。
  • 他的问题很笼统。所以这个答案可能是标题问题的答案
  • 您错误地使用了“静态”一词。在 C 中,static 描述了一个存储类。您还可以将非静态(即自动)结构设置为零。
  • 关于无法设置动态分配的观点是 100% 不正确的。在第二个示例中,您可以只使用 *a = (A){0}
猜你喜欢
  • 1970-01-01
  • 2018-02-13
  • 2016-03-23
  • 2021-06-16
  • 2017-04-07
  • 1970-01-01
  • 2012-09-23
  • 2021-02-13
相关资源
最近更新 更多