Moin.
Sehr schön: das Speicherleck bei Zuweisung neuer Werte von bezeichnung
und zusatzinfo
war mir entgangen, was du dank realloc()
vermeidest:
void set_str(char **c, const char *s) {
int len = strlen(s);
if (len>MAX) len=MAX;
*c = realloc(*c, (len+1)*sizeof(char));
if(!*c) { puts("Kein Speicher mehr(?!)\n"); exit(1); }
strncpy(*c, s, len);
}
Trotzdem steckt hier ein Bug: falls strlen(s) == MAX
, wird das Null-Endzeichen von s
nicht mitkopiert und *c
ist nur dann korrekt terminiert, falls zufälligerweise (*c)[len] == 0
.
Statt strncpy(*c, s, len)
sollte besser
memcpy(*c, s, len);
(*c)[len] = 0;
verwendet werden.
Außerdem ist es in Objekt-orientiertem C üblich, wie in Markus' ursprünglichem Code mit Zeigern auf die Strukturen zu arbeiten. Dabei wird der Code zur Speicherallokation und Initialisierung ausgelagert, was robuster ist: vergisst der Programmierer bei deiner Variante die Initialisierung mit Null-Zeigern, schlägt set_bez()
und set_zus()
fehl, da realloc()
dann ungültige Zeiger übergeben werden.
Ich würde daher folgendes Vorschlagen:
void kill_metadata(struct metadata *m)
{
free(m->bezeichnung);
free(m->zusatzinfo);
free(m);
}
struct metadata *create_metadata(void)
{
struct metadata *m = malloc(sizeof(*m));
if(!m) return NULL;
m->bezeichnung = NULL;
m->zusatzinfo = NULL;
return m;
}
int main(void)
{
struct metadata *m = create_metadata();
assert(m);
set_bez(m, "Erste Zeile");
set_zus(m, "Die zweite Zeile ist viel zu lang");
printf("m->bezeichnung = %s\n"
"m->zusatzinfo = %s\n", m->bezeichnung, m->zusatzinfo);
kill_metadata(m);
}
Christoph