Warum ist es sicherer, sizeof(*pointer) in malloc zu verwenden

Lesezeit: 4 Minuten

Benutzeravatar von Yu Hao
Yu Hao

Gegeben

struct node
{
     int a;
     struct node * next;
};

Um eine neue Struktur zu mallocieren,

struct node *p = malloc(sizeof(*p));

ist sicherer als

struct node *p = malloc(sizeof(struct node));

Wieso den? Ich dachte, sie sind gleich.

  • FYI, wenn es mit einer Variablen verwendet wird, sizeof braucht keine Eltern: p = malloc(sizeof*p);

    – Luser Drog

    23. Juni 2013 um 7:46 Uhr

  • Mit Klammern ist es besser lesbar

    – Tomer Arazy

    23. Juni 2013 um 7:48 Uhr

  • @ TomerArazy: Ich bin anderer Meinung; es ist weniger mit Klammern lesbar. Ohne Eltern, es kann nicht ein Typname sein; das Fehlen von Klammern hilft dem menschlichen Leser bei der Unterscheidung. (Kleines Problem: Die Klammern könnten auch darauf hindeuten, dass sizeof eine Funktion ist, was nicht der Fall ist.)

    – Wildpässer

    23. Juni 2013 um 9:18 Uhr

  • Es ist besser lesbar ohne Klammern, aber mit einem Leerzeichen: sizeof *p.

    – Eric Postpischil

    23. Juni 2013 um 11:47 Uhr

  • Es ist nicht besser lesbar mit Klammern oder ohne Klammern. Das sind Meinungen, keine Fakten. Tatsache ist jedoch, dass die Klammern nicht erforderlich sind, da sizeof als unärer Operator auf einen Ausdruck angewendet wird. Wenn Sie nicht immer Klammern mit allen unären Operatoren verwenden, warum verwenden Sie sie immer mit sizeof.

    – Kas

    23. Juni 2013 um 15:27 Uhr

AnT steht mit Russlands Benutzer-Avatar
AnT steht zu Russland

Es ist sicherer, weil Sie den Typnamen nicht zweimal erwähnen müssen und nicht die richtige Schreibweise für die „dereferenzierte“ Version des Typs erstellen müssen. Zum Beispiel müssen Sie nicht “die Sterne zählen”.

int *****p = malloc(100 * sizeof *p);

Vergleichen Sie das mit dem typbasierten sizeof in

int *****p = malloc(100 * sizeof(int ****));

wo Sie sicherstellen müssen, dass Sie die richtige Anzahl von verwendet haben * unter sizeof.

Um zu einem anderen Typ zu wechseln, müssen Sie nur eine Stelle ändern (die Deklaration von p) statt zwei. Und Menschen, die die Gewohnheit haben, das Ergebnis zu werfen malloc drei Plätze wechseln müssen.

Generell ist es sehr sinnvoll, sich an die folgende Richtlinie zu halten: Typnamen gehören in Deklarationen und nirgendwo anders hin. Die eigentlichen Anweisungen sollten typunabhängig sein. Sie sollten es so weit wie möglich vermeiden, Typnamen zu nennen oder andere typspezifische Merkmale zu verwenden.

Letzteres bedeutet: Vermeiden Sie unnötige Besetzungen. Vermeiden Sie unnötige typspezifische konstante Syntax (wie 0.0 oder 0L wo eine Ebene 0 würde genügen). Vermeiden Sie die Erwähnung von Typnamen unter sizeof. Usw.

  • Es ist nichts wert, dass es ausreicht, wenn der Typ geändert wird, ihn in der Deklaration von p zu ändern (eine Änderung in der malloc) bedeutet nicht nur weniger Arbeit, sondern auch weniger Fehlermöglichkeiten. Dies hilft also, Fehler zu reduzieren.

    – Eric Postpischil

    23. Juni 2013 um 11:49 Uhr

  • AndreyT, ich verstehe Ihren Punkt, abstrakt gesprochen … aber ich wette mit Ihnen, dass es in der Geschichte der Computer noch nie eine Plattform gegeben hat, auf der sizeof(int ****) != sizeof(int ***) 🙂

    – Josch

    19. Dezember 2014 um 23:41 Uhr

  • @Josh: Sie sagen im Grunde, dass Sie jedes Mal, wenn Sie die Zeigergröße wissen müssen, einfach verwenden können sizeof(double *). Ja, es wird funktionieren, aber solche Dinge sollten die gleiche Art von ungelöster Spannung erzeugen wie eine nicht übereinstimmende linke Klammer (xkcd.com/859)

    – AnT steht zu Russland

    19. Dezember 2014 um 23:50 Uhr


Benutzeravatar von Alok Save
Alok Speichern

Denn wenn zu einem späteren Zeitpunkt p wird gemacht, um auf einen anderen Strukturtyp zu zeigen, als Ihre Speicherzuweisungsanweisung verwendet malloc muss sich nicht ändern, es weist immer noch genug Speicher zu, der für das Neue erforderlich ist Typ. Es gewährleistet:

  • Sie müssen die Speicherzuweisungsanweisung nicht jedes Mal ändern, wenn Sie die ändern Typ es weist Speicher zu.
  • Ihr Code ist robuster und weniger anfällig für manuelle Fehler.

Im Allgemeinen ist es immer eine gute Praxis, sich nicht auf konkrete Typen zu verlassen, und die erste Form tut dies einfach, sie codiert einen Typ nicht fest.

Benutzeravatar von ruben2020
ruben2020

Es ist praktisch, weil Sie dies umwandeln können:

struct node *p= malloc(sizeof(*p));

Das mögen:

#define MALLOC(ptr)   (ptr) = malloc(sizeof(*(ptr) ))

struct node *p;
MALLOC(p);

Oder für ein Array:

#define MALLOC_ARR(ptr, arrsize) \
       (ptr) = malloc(sizeof(*(ptr) ) * arrsize)

struct node *p;
MALLOC_ARR(p, 20);

Und warum ist das sicher? Weil der Benutzer, der diese Makros verwendet, weniger wahrscheinlich Fehler macht, die von AndreyT beschrieben wurden, genau wie im Fall von DIM() um die Größe eines statischen Arrays zu erhalten.

#define DIM(arr)   ((sizeof(arr))/(sizeof(arr[0])))

Dies ist auch sicherer, da der Benutzer die statische Array-Größe nicht an mehreren Stellen konsistent machen muss. Stellen Sie die Array-Größe an einer Stelle ein und verwenden Sie dann einfach die DIM() und du bist fertig! Der Compiler erledigt das für Sie.

  • Normalerweise verdienen Makroargumente a ()Also .... * arrsize) –> ... * (arrsize)).

    – chux – Wiedereinsetzung von Monica

    10. Februar 2021 um 18:46 Uhr

1410890cookie-checkWarum ist es sicherer, sizeof(*pointer) in malloc zu verwenden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy