Soll ich prüfen, ob malloc() erfolgreich war?

Lesezeit: 4 Minuten

Benutzeravatar von gen
Gen

Sollte man nach jedem prüfen malloc() ob es erfolgreich war? Ist es überhaupt möglich, dass a malloc() scheitert? Was passiert dann?

In der Schule wurde uns gesagt, dass wir überprüfen sollten, dh:

arr = (int) malloc(sizeof(int)*x*y);
if(arr==NULL){
    printf("Error. Allocation was unsuccessful. \n");
    return 1;
}

Wie ist die diesbezügliche Praxis? Kann ich das so machen:

if(!(arr = (int) malloc(sizeof(int)*x*y))
    <error>

  • Theoretisch ja. Wenn malloc fehlschlägt, steht das Betriebssystem wahrscheinlich kurz vor dem Absturz. PS: Ihr zweites Beispiel ist viel schwieriger zu lesen als das erste und sollte von einem Code-Review abgelehnt werden.

    – Steve Wellens

    9. November 2014 um 18:54 Uhr


  • arr = (int) malloc(...) ist falsch, malloc gibt einen Zeiger zurück. Abgesehen davon: ja, Sie sollten prüfen, ob es fehlschlägt, weil es fehlschlagen kann. Außerdem ist das Gießen des Rückgabewerts schädlich.

    – Das paramagnetische Croissant

    9. November 2014 um 18:54 Uhr


  • 1. Sie brauchen den Gips nicht. 2. Ja überprüfen – warum nicht

    – Ed heilen

    9. November 2014 um 18:54 Uhr

  • @SteveWellens Ich würde sagen, dass es in Theorie und Praxis ja ist, besonders wenn große Puffer zugewiesen werden.

    – Alex D

    9. November 2014 um 18:57 Uhr

  • @AlexD – Stimmt. Aber wenn Sie einen Puffer zuweisen, der so groß ist, dass malloc fehlschlagen kann, dann würde ich sagen, dass ein Re-Design angebracht ist.

    – Steve Wellens

    9. November 2014 um 18:59 Uhr

Benutzeravatar von Vality
Wertigkeit

Dies trägt hauptsächlich nur zur vorhandenen Antwort bei, aber ich verstehe, woher Sie kommen. Wenn Sie viel Speicher zuweisen, sieht Ihr Code mit all den Fehlerprüfungen für malloc sehr hässlich aus.

Persönlich umgehe ich dies oft mit einem kleinen Malloc-Wrapper, der niemals fehlschlägt. Wenn Ihre Software kein belastbares, sicherheitskritisches System ist, können Sie das Fehlschlagen von Malloc sowieso nicht sinnvoll umgehen, daher würde ich so etwas vorschlagen:

static inline void *MallocOrDie(size_t MemSize)
{
    void *AllocMem = malloc(MemSize);
    /* Some implementations return null on a 0 length alloc,
     * we may as well allow this as it increases compatibility
     * with very few side effects */
    if(!AllocMem && MemSize)
    {
        printf("Could not allocate memory!");
        exit(-1);
    }
    return AllocMem;
}

Dadurch wird zumindest sichergestellt, dass Sie eine Fehlermeldung und einen sauberen Absturz erhalten und der Großteil des Fehlerprüfcodes vermieden wird.

Für eine allgemeinere Lösung für Funktionen, die fehlschlagen können, neige ich auch dazu, ein einfaches Makro wie dieses zu implementieren:

#define PrintDie(...) \
    do \
    { \
    fprintf(stderr, __VA_ARGS__); \
    abort(); \
    } while(0)

Damit können Sie eine Funktion ausführen als:

if(-1 == foo()) PrintDie("Oh no");

Dadurch erhalten Sie einen Einzeiler, der wiederum die Masse vermeidet und gleichzeitig ordnungsgemäße Überprüfungen ermöglicht.

  • Dein PrintDie sollte anrufen abortnicht exit. Da das Debuggen einfacher wäre (unter Linux erhalten Sie sogar eine core dump, mit dem Sie Post-Mortem analysieren könnten gdb)

    – Basile Starynkevitch

    10. November 2014 um 13:17 Uhr

  • @BasileStarynkevitch Danke, hatte alles über Abbruch vergessen, das Beispiel geändert, um es jetzt zu verwenden.

    – Wertigkeit

    10. November 2014 um 13:45 Uhr

  • if(NULL == AllocMem) ist der falsche Test. Mit MemSize == 0Empfangen eines malloc() Rückgabewert von NULL ist konformes Verhalten und kein Zuordnungsfehler. Wechseln zu if(NULL == AllocMem && MemSize != 0) behebt das.

    – chux – Wiedereinsetzung von Monica

    15. November 2014 um 13:03 Uhr


  • @chux Sie haben Recht, dass dies für die meisten Implementierungen ein wünschenswertes Verhalten ist. Im Standard ist es etwas schwierig, wie es heißt (in C99 und C11): “Wenn die Größe des angeforderten Speicherplatzes Null ist, ist das Verhalten implementierungsdefiniert ” (7.22.3 P1, ISO-C11). Was Sie jedoch vorschlagen, ist eine gemeinsame Implementierung in vielen Compilern, daher werde ich dem Code eine Überprüfung mit einer Notiz hinzufügen. Vielen Dank.

    – Wertigkeit

    15. November 2014 um 21:58 Uhr

  • @Ayxan sieht so aus. Obwohl ich xmalloc noch nie gesehen habe, da ich nie auf BSD entwickelt habe. Sieht aber nach einer nützlichen Funktion aus. Dabks für die Info.

    – Wertigkeit

    20. Mai 2020 um 19:39 Uhr

Benutzeravatar von Gopi
Gopi

Keine Notwendigkeit zu werfen malloc(). Ja, es muss jedoch geprüft werden, ob die malloc() erfolgreich war oder nicht. Sagen wir malloc() ist fehlgeschlagen und Sie versuchen, auf den Zeiger zuzugreifen, weil Sie denken, dass Speicher zugewiesen wird, was zu einem Absturz führen wird. Daher ist es besser, den Fehler bei der Speicherzuweisung abzufangen, bevor Sie auf den Zeiger zugreifen.

int *arr = malloc(sizeof(*arr));
if(arr == NULL)
{
printf("Memory allocation failed");
return;
}

  • Um es pedantisch anzumerken, fördert diese Antwort “überprüfen Sie, ob malloc () erfolgreich war oder nicht” – was eine gute Idee ist. Aber dann zeigt es, wie man das Ergebnis überprüft malloc(sizeof(int)) und nicht OPs malloc(sizeof(int)*x*y). Testen gegen NULL reicht dafür aus sizeof(int)aber falsch für OPs sizeof(int)*x*y. Sollte x*y –> 0, a NULL return ist konformer Code und zeigt keine Speicherzuweisung an. Besser zu verwenden if(arr == NULL && x != 0 && y != 0).

    – chux – Wiedereinsetzung von Monica

    15. November 2014 um 14:08 Uhr

1432750cookie-checkSoll ich prüfen, ob malloc() erfolgreich war?

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

Privacy policy