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>
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.
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;
}
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