0

我正在使用一个包含许多成员的大型结构,我想要一种简单的方法来快速查看是否有任何成员非零。我知道memcmp()不应该用它来比较两个结构的相等性(如此处所述:如何比较结构在 C 中的相等性?),但我希望通过将结构与已设置为 0 的内存块进行比较,这可能有效。

例如,假设我有一些结构:

typedef struct {
    int Int1;
    int Int2;
    int Int3;
} MyInts;

我从这个结构创建一个变量:

MyInts MyStruct = {0};

在我的程序执行过程中,成员MyStruct通常为 0,但有时可能会临时设置为某个非零值。我想快速检查其中的任何整数MyStruct是否非零。我可以memcmp()像下面这样使用吗?

// Create empty struct to test against
MyInts EmptyStruct = {0};

// Make sure entire memory block of test struct is cleared
memset(&EmptyStruct, 0, sizeof(MyInts));

// Compare MyStruct to EmptyStruct to see if any non-zero members exist
int result = memcmp(&MyStruct, &EmptyStruct, sizeof(MyInts));
4

2 回答 2

0

为了清楚起见,我决定继续根据评论回答我自己的问题。正如@MM 所提到的,填充不能保证被结构分配保留,也可能不被单个成员分配保留。因此,memcmp用于检查结构中的非零成员是不安全的。

正如ShadowRanger 建议的那样,安全的方法是单独比较每个结构成员。

于 2016-10-14T05:25:27.890 回答
0

在一般情况下您不能这样做,因为结构可以在字段之间和结构末尾进行填充,并且不能保证填充字节的内容(可能是未初始化的垃圾)。

如果两个被比较的结构最初都分配有calloc,或者在填充实际值之前sizeof(thestruct)字节memset为零,那么填充将具有可预测的值,并且memcmp可以工作。同样,如果您可以保证没有填充,那么这memcmp将起作用。但是,如果其中一个可能没有被归零,不,不安全。

当然,如果你想变得“好”,你可以直接比较成员,可能在一个分解的函数中,让编译器处理优化,而不用担心你是否有未归零的结构和填充浮动。

注意:您提供的链接中投票第二高的答案涵盖了这一点。对该答案的评论还指出了一些边缘情况,例如floats 可以具有比较相等但具有不同位表示的值,因此即使如此,它也不能推广到所有结构。

于 2016-10-14T02:58:18.977 回答