在我们的代码中我们曾经有过这样的事情:

   *(controller->bigstruct) = ( struct bigstruct ){ 0 };

这一工作很大的,然后我们升级版本的海湾合作委员会和突然开始看到一堆溢出。看大会,旧的海湾合作委员会代码(2中。x)基本上是这样做:

memset(controller->bigstruct, 0, sizeof(struct bigstruct));

新的海湾合作委员会(3.4.x)这样做

   struct bigstruct temp = { 0 };
   controller->bigstruct = temp;

在审查C99规格,我可以看到为什么;C99基本上要求匿名结构上存在的叠。这是一个很好的概念,但这个结构是4兆字节大,而只打算存在堆!

我们已经采取了使我们自己的'初始化'功能的明确组成员,但是丑恶和维护头痛的问题。我不认为memset一个适当的解决方案,因为我不能知道这一点价值的0是一个适当的零价值的类型(吹毛求疵,我知道,但你是;我不介意的编译器,因为它 可以 知道)

什么是"正确的",或者至少是最好的方式来初始化的大型结构这样吗?

要进一步澄清为什么我认为memset不是一个解决方案:该规则的初始化的成员没有明确的初始化是相同的作为静态的初始化,如下:-如果它有针类型,这初始化为一个空的指针;-如果它有算术类型,这初始化(正或符号)零;...

'memset'将设置存储位模式的零,这不一定是相同的事情。想象一下,一个系统,该系统不使用IEEE浮点数。不寻常的,但是支持通过C.表0.0并不意味着"所有零位",它可能是任何东西方便的处理器。

有帮助吗?

解决方案

memset是的路要走。你没有许多替代品。

做喜欢的东西:

#define InitStruct(var, type) type var; memset(&var, 0, sizeof(type))

所以你只要:

InitStruct(st, BigStruct);

然后使用st像往常一样...

我不觉得如何"0"不是一个有效的"0"类型的结构。唯一的方式"量化"一个结构来设置的所有其存到一个值;否则你就必须做出额外的逻辑告诉它使用一个特定的位模式的每个成员。最好的"通用"位模式的使用是0.

除了-这是同一逻辑的时使用这样做

*(controller->bigstruct) = *( struct bigstruct ){ 0 };

因此我不得你不愿意使用它:)

第一个评论到这个职位使我做一些研究之前,我叫他白痴,我找到这个:

http://www.lysator.liu.se/c/c-faq/c-1.html

非常有趣;如果我可以投票立一个评论,我将:)

这就是说-你唯一的选择,如果你想要的目标的古老的结构与非0空值是仍然要做手册的初始化的某些成员。

谢谢托马斯*帕德龙-麦卡锡!我学到新的东西今天:)

其他提示

如果您不想使用memset,您可以随时声明结构的静态副本并使用memcpy,这将提供类似的性能。这将为您的程序添加4兆,但可能比设置单个元素更好。

那就是说,如果GCC使用的是memset,之前已经足够好了,我建议现在已经足够好了。

正如其他人所说,memset是要走的路。但是,在C ++对象上使用memset,特别是那些使用虚方法的对象。 sizeof(foo)将包含虚函数指针表,并在其上执行memset将导致严重的悲痛。

如果memset本身没有解决问题,只需执行一个memset然后然后初始化任何非零的成员(即你的非IEEE浮点值)。

私有初始化函数并不是一个很好的OO方式来初始化对象(结构)。我假设你的结构不是4MB的指针,所以我认为解决方案应该是这样的:

void init_big_struct(struct bigstruct *s)  
{  
    memset(s, 0, sizeof(struct bigstruct));  
    s->some_pointer = NULL; // Multiply this as needed  
}

从另一方面来说,我们的代码运行在20多个嵌入式操作系统和大量不同的硬件上,从不会遇到任何只有memset的问题。

嗯 - 首先制作一个init函数并明确地设置每个成员是正确的 - 它是OO语言中构造函数的工作方式。

和第二 - 有没有人知道实现非IEEE浮点数的硬件? - 也许Commodore 64或somethig; - )

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top