PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : zweites malloc nicht ausgeführt wenn in if-Abfrage



awehrm
01-08-2006, 10:12
Hallo!

Ich habe folgenden Code:



if((article=(Article*)malloc(sizeof(Article)*MAX_E NTRIES)) == NULL && (cat=(Category*)malloc(sizeof(Category)*MAX_ENTRIE S)) == NULL)
{
printf("\nMemory allocation failed!\nExiting...\n");
exit(1);
}

.
.
.
.

if(!(*article_amount))
{
memset((void*)article,0,MAX_ENTRIES*sizeof(Article ));
}

if(!(*cat_amount))
{
memset((void *)cat,0,MAX_ENTRIES*sizeof(Category));
}


Es soll für beide Structs entsprechend Speicher für ein Array alloziert werden.
MAX_ENTRIES ist ein per #define definierter Wert von 4*1024.
Theoretisch müssten beide Allozierungen durchgeführt werden, da beide
Bedingungen per UND verknüpft sind.
Ich habe aber festgestellt, dass in diesem Falle nur Speicher für article
angefordert wird.
Wenn ich die Pointer nämlich überprüfe sagt mir das Programm bei cat jediglich "(nil)", also hat gar keine Allozierung stattgefunden.
Später stürzt das Programm dann natürlich bei memset ab.
Im Moment habe Ich einfach zwei If-Abfragen hintereinander geschrieben, was aber unschön aussieht.
Müsste der erste Weg denn nicht auch möglich sein?

OpOs
01-08-2006, 11:08
ein tip ins blaue:

der operator && ist hoeherrangig als ==, also wird zuerst der part "NULL &&..." ausgefuehrt, und da eine UND-verknuepfung mit NULL immer NULL ergibt, wird der 2. teil gar nicht erst ausgefuehrt.

ich rate dir zu extensivem gebrauch von klammern!

Pingu
01-08-2006, 11:49
Außerdem ist die UND-Verknüpfung falsch.

Denn was passiert, wenn Du noch genau soviel Speicher hast, daß nur die erste Speicherzuweisung von Erfolg gekrönt ist, die zweite aber nicht?

Pingu

awehrm
01-08-2006, 16:11
@OpOs:
Das hatte ich auch schon gemacht, leider mit keinem Erfolg, ich bekomme nach
wie vor ein Segmention-Fault als Fehlermeldung.

@Pingu:
Dann soll das Programm abbrechen, weil dann gar nicht erst weiter gearbeitet
werden braucht.

Pingu
01-08-2006, 16:16
Dann schaue Dir Deinen Konstrukt noch einmal genau an und denke noch mal nach. Oder besser schreibe alle 4 Fälle auf, dann wird Dir etwas auffallen.

Pingu

OpOs
01-08-2006, 16:24
pingu hat recht, da muss ein "||" hin, ansonsten wird nur abgebrochen, wenn beide anforderungen fehlschlagen

awehrm
01-08-2006, 17:32
gibt es hier im forum eine ecke, in die ich mich stellen kann? *schäm*

Jinto
01-08-2006, 19:44
Zudem sehe ich da ein hässliches memory leak im Falle eines fehlschlagens beim zweiten malloc.

PS: Warum weigern sich so viele Leute else zu verwenden?

Pingu
01-08-2006, 19:46
Sehe ich auch.

Pingu

awehrm
01-08-2006, 20:33
Wird nicht der gesamte vom Programm angefordete Speicher spätestens bei Beendigung des Programms wieder freigegeben?

Pingu
02-08-2006, 05:34
Kommt auf den Compiler sowie auf das Betriebssystem an. Jedenfalls sollte man sich nie darauf verlassen.

Pingu

awehrm
02-08-2006, 08:02
Alles klar, danke für den Tipp.

Joghurt
03-08-2006, 20:54
So ist's schöner:
void* xmalloc(size_t size) {
void* retval = malloc(size);
if (retval == NULL) {
fprintf(stderr, "Kein Speicher mehr!");
exit(1);
} // else
return retval;
}

....
article=(Article*)xmalloc(sizeof(Article[MAX_ENTRIES]));
cat=(Category*)xmalloc(sizeof(Category[MAX_ENTRIES]));

awehrm
05-08-2006, 10:12
hmm, lecker, das is natürlich noch besser

Jinto
06-08-2006, 20:06
Nein, nicht ganz, das memory leak bleibt (ganz besonders, wenn man irgendwann auch noch das exit wegrationalisiert).