Bus Error
-
Hallo,
ich habe einen Program geschrieben, das mit einem 2-dim-arrays arbeiten muss.Das Array soll dynamisch estellt werden. Dafür habe ich folgendes code geschrieben:
int** mymalloc(int nmax){ int **f,i,j; /*Speicherplatz für den zeigervektor reservieren*/ if((f = (int **)malloc(nmax*sizeof(int *))) == NULL) { fprintf(stderr, "Couldn't allocate memory\n"); return NULL; } /*Initialisiere das Zeigervektor*/ for(i = 0; i < nmax; i++) f[i] = NULL; /*Speicherplatz für die eigentliche Daten reservieren*/ for(i = 0; i < nmax; i++){ if((f[i] = (int *)malloc(nmax*sizeof(int))) == NULL) { fprintf(stderr, "Couldn't allocate memory\n"); return NULL; } } for(i = 0; i < nmax; i++) for(j = 0; j < nmax; j++) f[i][j] = 0; return f; }
Das functioniert soweit gut! Die hauptschleife des Programms läuft 4-5 mal, macht ihr Arbeit vernünftig wie es sein soll, und dann kommt win unangenemes "Bus Error". Das programm wird also unterbrochen.
Ich verstehe nicht wo das Problem liegt.
Jemand hat eine Idee?
Danke im voraus.
-
Erstmal: Die Rückgabe von malloc() castet man nicht (wenn dein Compiler sich darüber beschwert, solltest du den richtigen verwenden ;)). Und wenn in deiner for(i)-Schleife ein malloc-Aufruf fehlschlägt, solltest du die bisher reservierten Speicherbereiche auch wieder freigeben, bevor du NULL ausgibst, sonst erhältst du ein Speicherleck.
Zweitens: welches ist die Hauptschleife, die dir Probleme macht? In dem Code sehe ich schon vier Schleifen.
PS: Und die erste Schleife ist nebenbei überflüssig - wozu füllst du das Array erst mit Nullen, wenn du es sofort wieder mit echtehn Speicheradressen füllen willst?
-
Warum castet man den Rückwert von malloc() nicht? Ich dachte das muss man sogar machen, da malloc() einen Zeiger auf "nichts" liefert. (ich benutze gcc, und er meckert nicht
)
Du hast Recht gehabt. Man muss erstmal den Speicher frei lassen bevor man NULL zurückgibt.
Die letzte for-schleife ist überflüssig (das kam aus Verzweiflung).
Dieser Code produziert keinen Fehler. Die Fehler habe ich inzwischen (Nacht um 3:00) gefunden. Ich habe einen Indexüberlauf im Code gehabt.
http://de.wikipedia.org/wiki/Um-eins-daneben-Fehler
-
morgol schrieb:
Warum castet man den Rückwert von malloc() nicht? Ich dachte das muss man sogar machen, da malloc() einen Zeiger auf "nichts" liefert. (ich benutze gcc, und er meckert nicht
)
Weil du mit diesem Cast nur weiterreichende Fehler maskierst. Ja, malloc() liefert einen void* zurück (aber das ist kein "Zeiger auf nichts", sondern ein "Zeiger auf unstrukturierte Daten), aber in C kannst du einen void* problemlos in einen beliebigen Zeigertyp konvertieren.
-
Danke CStoll für die Antwort!
CStoll schrieb:
mit diesem Cast nur weiterreichende Fehler maskierst.
hast du vielleicht ein Beispiel wo es so ist?
-
Für den konkreten Fall gerade nicht. Aber allgemein habe ich gelernt, daß Casts (gerade die C-Variante) schlecht sind.
Zum Beispiel kann dir der Compiler normalerweise mitteilen, daß du einen int-wert keiner Pointer-Variablen zuweisen kannst. Die Fehlermeldung kannst du unterdrücken, indem du den int explizit nach char* castest - das sagt dem Compiler in etwa "vertrau mir, ich weiß, was ich da tue". Der wirkliche Fehler (egal wie du ihn castest, ein int-Wert ist nunmal keine Speicheradresse) wird dadurch aber nicht behoben.
-
Für den casten der malloc()-Rückgabe habe ich folgendes gefunden: http://www.dclc-faq.de/kap3.htm#3.5
-
Wer benutzt heutzutage noch Prä-ANSI-Compiler? (und über C++ rede ich hier nicht - dort sollte man sowieso new/delete verwenden)
Ein Problem, das du durch diesen Cast vertuschst, wäre z.B. eine fehlende Lib. Wenn du vergessen hast, die stdlib.h einzubinden, wird beim ersten geeigneten Aufruf ein Prototyp 'int malloc()' (die leeren Klammern stehen für eine beliebige Argumentliste im K&R-Stil) angelegt und der Compiler stellt fest, daß er int nicht nach char* umwandeln kann. Wenn du dort einen Cast drumherum legst, zwingst du ihn, diese Umwandlung doch durchzuführen. (ob du die korrekten Parameter übergeben hast, kann er mit dieser Deklaration allerdings nicht feststellen)
-
Ich sehe was du meinst!
Danke!