Ich weiß, dass memcmp()
nicht verwendet werden kann, um Strukturen zu vergleichen, die nicht memset()
auf 0 wegen der nicht initialisierten Auffüllung waren. In meinem Programm habe ich jedoch eine Struktur mit ein paar verschiedenen Typen am Anfang, dann mehrere Dutzend vom selben Typ bis zum Ende der Struktur. Mein Gedanke war, die ersten paar Typen manuell zu vergleichen und dann einen memcmp()
auf dem verbleibenden zusammenhängenden Speicherblock derselben typisierten Mitglieder zu verwenden.Vergleichen Sie Strukturen in C mit memcmp() und Zeigerarithmetik
Meine Frage ist, was garantiert der C-Standard über Strukturauffüllung? Kann ich dies bei einigen oder allen Compilern zuverlässig erreichen? Ermöglicht der C-Standard das Einfügen von Struct-Padding zwischen denselben Typmitgliedern?
Ich habe meine vorgeschlagene Lösung umgesetzt, und es scheint, genau zu arbeiten, wie mit gcc
bestimmt:
#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;
}
Minor: Da Ihr Zeiger vergleicht, gibt 0 oder 1 zurück, was darauf hindeutet, dass 'memcmp()' mit 'memcmp()! = 0' 0 oder 1 zurückgibt. – chux
@chux Gute Idee, danke für den Vorschlag. – John