使用结构记忆结构好吗?

use*_*337 3 c linux signals

一旦我学会了信号,便有了处理信号的清单。

有一个struct sigaction这是第一次memset()有以下行的所有字节为零:

memset(&sa, 0, sizeof(sa));
Run Code Online (Sandbox Code Playgroud)

而且我不确定为什么作者使用这种方法。

Jon*_*ler 5

正如您已经被告知的那样,尝试从结构的未初始化成员中读取值会导致未定义的行为。那是无条件的坏。因此,您有责任确保在读取所有字段之前对其进行初始化。

如果您知道该结构的所有元素并打算显式初始化它们,则memset()没有必要。如果结构处于您的控制之下,则这是可以管理的—您只需记住要确保在向结构中添加新成员时,所有进行初始化的位置都已更新。如果您编写了一个函数来做到这一点(想想“ C ++构造函数的C类似物”,一阶近似),那么memset()可以忽略该函数。如果您在许多地方临时设置值,则结构更改可能会出现问题。

对于类似的情况struct sigaction,它来自系统定义的标头,并且不同的系统可以(并且确实)向结构中添加额外的字段-在您计划初始化的字段之上。请注意,POSIX仅指定必须存在的字段。它不决定字段的顺序,也不要求结构中没有其他字段。但是,使用结构的多余(非POSIX)元素的函数不应这样做,除非用户指示通常使用一些显式标志初始化那些成员,所以您不应该遇到问题-但这样做更安全比对不起。

因此,在您无法控制结构的情况下,这种memset()方法很容易辩护:即使结构定义发生变化(增长),也可以保证将所有结构(即使您不知道的位)都清零。编写代码后。

您也许可以使用该结构struct sigaction sa = { 0 };struct sigaction *sap = calloc(sizeof(*sap), 1);将其置零,这部分取决于所使用的一组编译器选项的繁琐程度(以及所用编译器的版本;例如,GCC随着时间的推移已更改其行为)。

您可能想要查找诸如PTHREAD_MUTEX_INITIALIZERPOSIX标准中的宏,或者您可能希望完全忽略它们的存在。