Tôi biết rằng không thể sử dụng memcmp()
để so sánh các cấu trúc chưa được memset()
đến 0 vì đệm không được khởi tạo. Tuy nhiên, trong chương trình của tôi, tôi có một cấu trúc với một vài loại khác nhau khi bắt đầu, sau đó vài chục cùng loại cho đến khi kết thúc cấu trúc. Suy nghĩ của tôi là so sánh thủ công một vài loại đầu tiên, sau đó sử dụng memcmp()
trên khối bộ nhớ tiếp giáp còn lại của cùng một thành viên đã nhập.So sánh cấu trúc trong C bằng cách sử dụng memcmp() và số học con trỏ
Câu hỏi của tôi là, tiêu chuẩn C đảm bảo về cấu trúc đệm là gì? Tôi có thể đạt được điều này một cách đáng tin cậy trên bất kỳ hoặc tất cả các trình biên dịch không? Liệu các tiêu chuẩn C cho phép cấu trúc đệm được chèn vào giữa các thành viên cùng loại?
tôi đã thực hiện giải pháp đề xuất của tôi, và có vẻ như để làm việc chính xác như dự định với gcc
:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct foo
{
char a;
void *b;
int c;
int d;
int e;
int f;
};
static void create_struct(struct foo *p)
{
p->a = 'a';
p->b = NULL;
p->c = 1;
p->d = 2;
p->e = 3;
p->f = 4;
}
static int compare(struct foo *p1, struct foo *p2)
{
if (p1->a != p2->a)
return 1;
if (p1->b != p2->b)
return 1;
return
/* Note the typecasts to char * so we don't get a size in ints. */
memcmp(
/* A pointer to the start of the same type members. */
&(p1->c),
&(p2->c),
/* A pointer to the start of the last element to be compared. */
(char *)&(p2->f)
/* Plus its size to compare until the end of the last element. */
+sizeof(p2->f)
/* Minus the first element, so only c..f are compared. */
-(char *)&(p2->c)
) != 0;
}
int main(int argc, char **argv)
{
struct foo *p1, *p2;
int ret;
/* The loop is to ensure there isn't a fluke with uninitialized padding
* being the same.
*/
do
{
p1 = malloc(sizeof(struct foo));
p2 = malloc(sizeof(struct foo));
create_struct(p1);
create_struct(p2);
ret = compare(p1, p2);
free(p1);
free(p2);
if (ret)
puts("no match");
else
puts("match");
}
while (!ret);
return 0;
}
Nhỏ: Vì so sánh con trỏ của bạn đang trả về 0 hoặc 1, gợi ý việc đảm bảo 'memcmp()' trả về 0 hoặc 1 với 'memcmp()! = 0'. – chux
@chux Ý tưởng hay, cảm ơn đề xuất. – John