realloc zerhackt Werte
-
denk der fehler beginnt wenn dann schon hier:
a = (struct array *)realloc(a, new_size);
-
Stimmt, da steckt auch noch der Wurm drin. Es muß
a->mem = (struct array *)realloc(a->mem, new_size);
heißen.
a->mem=a+1
muß dann ganz weg usw.
-
Hmm, sry, das hätte ich noch anmerken sollen: a->mem zeigt auf das erste frei Byte HINTER der Array-Struktur im Speicher.
D.h. das Array wird an der Adresse von a abgespeichert, die Items an der Adresse a + 1 (Zeigerarithmetik...).
Von daher muss ich a->mem neu setzen.
(Ich hab die Ändern auch ausprobiert, das führt zum totalen Speichercrash des Programms)
-
Leicht vereinfacht sieht eine korrigierte Fassung z.B. so aus:
typedef struct { size_t memsize; // Größe des reservierten Speichers auf den men zeigt size_t itemsize; // Die Größe eines Array-Elements unsigned long itemcount;// Die Anzahl der sich im Array befindendenen Elemente void *mem; // Zeiger auf den für das Array reservierten Speicher int test; } Array; Array *addArrayItem(Array *a, void *item) { if( a->memsize < (a->itemcount+1)*a->itemsize) { // nicht mehr genügend Platz für neues Item a->mem = realloc( a->mem, (a->itemcount+1)*a->itemsize ); if( !a->mem ) return 0; } // Element anhängen; Adresse zum Anhängen: Adresse von Array + Itemanzahl*Itemgröße memcpy(a->mem + a->itemsize*a->itemcount, item, a->itemsize); a->itemcount++; // Itemanzahl erhöhen return a; }
-
Wie gesagt, dass führt leider zum invalid pointer Fehlermeldungen.
a->mem wurde ja vorher nicht mit malloc() Speicher zugewiesen. Das Array wurde so initialisiert:
struct array *a1 = (struct array *)malloc(sizeof(struct array) + 20); a1->itemsize = (size_t)4; a1->memsize = (size_t)20; a1->itemcount = (unsigned long)0; a1->test = -1;
Nochmal zur Erklärung:
Ich will im Speicher eine Array-Struktur ablegen. Hinter der Array-Struktur sollen die Array-Items folgen.
-
Wenn du das Folgende verwendest
struct array *a1 = (struct array *)calloc(1,sizeof*a1); a1->itemsize = 4; a1->test = -1;
steht erstmal alles mem-Relevante auf 0/NULL und das erste realloc schlägt auch nicht mehr fehl.
-
Hm, aber ich versteh einfach nicht warum realloc in meinem Code die ersten paar (aber nicht alle) Werte zerhackt (und auch nur auf linux...)
calloc beim initialisieren hilft auch nichts
-
Du hast nicht viel verstanden.
calloc initialisiert immer, malloc nie, egal was du vermutest.
Führe den Beispielcode im Debugger aus und du lernst.
Gehe davon aus, dass realloc genauso arbeitet wie spezifiziert und wenn etwas nicht deinen Erwartungen entspricht, liegt es immer an dir und deinem Code ("der Compiler hat immer Recht").
-
Konfusius schrieb:
Stimmt, da steckt auch noch der Wurm drin. Es muß
a->mem = (struct array *)realloc(a->mem, new_size);
heißen.
sry. aber wenn ich meine doku richtig gelesen hab ist das immernoch falsch
-
Hallo,
Warum ist dir das so wichtig, dass das Array direkt hinter der Struktur liegt? Weil dadurch musst du umständlich mit Zeigern hantieren...
Die Lösung von Wutz finde ich wesentlich übersichtlicher und intuitiver :).
-
Hi nochmal,
mir ist es so wichtig, da es meine Vorgaben so verlangen
Es ist mir schon klar, dass malloc nicht initialisiert. ICH initialisiere den mit malloc reservierten Speicherbereich aber (wie angegeben). Und genau die Initialisierungen zerhackt mir realloc zumindest partiell und ich verstehe nicht warum. Eine Antwort darauf hab ich bisher auch nicht herauslesen können.
Und der Vorschlag mit calloc hat außer weiteren Fehlermeldungen nichts gebracht. Von daher habe ich daraus auch nichts lernen können.
Achja, [unregistrierter Benutzer] war nicht ich
-
Du holst beim realloc nur Speicher für das (vergrößerte) Array, nicht für die Struktur selbst.
-
Also werden die alten Initialisierungen doch nicht mitkopiert?
Aber es hieß doch:
Du brauchst den Inhalt des alten Speicherbereichs nicht selbst in den neuen zu kopieren. Das macht realloc() automatisch.
-
wertixx schrieb:
Also werden die alten Initialisierungen doch nicht mitkopiert?
Es geht nicht um's kopieren. Du holst einfach nicht genug Speicher.
Du holst mit realloc new_size Bytes für Struktur und Array, tust aber im weiteren Verlauf so, als wären new_size Bytes für das Array allein da.
-
Oh man, jetzt hat es klick gemacht
Ich hab bei newSize vergessen, den Speicherplatz für die Struktur mit einzuberechnen.
Es hätte
size_t new_size = sizeof(struct array *) + a->memsize + (size_t)(a->itemsize*ADD);
lauten müssen. Da war ich echt ne Blindschleiche...
Danke für die vielen antworten