초기화되지 않은 패딩 때문에 memset()
이 아닌 구조체를 비교하는 데 memcmp()
을 사용할 수 없다는 것을 알고 있습니다. 그러나, 내 프로그램에서 시작 부분에 몇 가지 다른 유형의 구조체가 있고, 구조체가 끝날 때까지 동일한 유형이 여러 개 있습니다. 내 생각은 처음 몇 가지 유형을 수동으로 비교 한 다음 동일한 유형의 구성원으로 남아있는 인접한 메모리 블록에 memcmp()
을 사용하는 것이 었습니다.memcmp() 및 포인터 산술을 사용하여 C 구조체 비교
제 질문은 C 표준이 구조체 패딩을 어떻게 보장합니까? 일부 또는 모든 컴파일러에서이를 안정적으로 얻을 수 있습니까? C 표준은 동일한 유형 멤버간에 구조체 패딩을 삽입 할 수 있습니까?
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;
}
보조 : 포인터 비교가 0 또는 1을 반환하므로'memcmp()'는'memcmp()! = 0'을 사용하여 0 또는 1을 반환합니다. – chux
@chux 좋은 아이디어, 제안에 감사드립니다. – John