Ich bin vor allem an der Lebensfähigkeit von Schrumpf so ein Array interessiert.Verwenden Sie realloc() auf einem dynamisch zugewiesenen 2D-Array eine gute Idee?
Ich arbeite an einem Projekt, bei dem ich einzelne malloc() - Aufrufe verwendet habe, um einzelne mittelgroße 2D-Arrays zu erstellen. (Jeweils nur einige Dutzend MiB, höchstens.) Die Sache ist, dass über die Lebensdauer eines der Arrays sein Inhalt dramatisch in der Größe schrumpft (um mehr als die Hälfte). Offensichtlich könnte ich die Array-Größe einfach für die gesamte Lebensdauer des Programms belassen. (Es ist nur eine x MiB auf einem System mit GiB RAM verfügbar.) Aber wir sprechen davon, dass mehr als die Hälfte des zugewiesenen Speicherplatzes lange bevor das Programm beendet wird, und aufgrund der Art, wie ich bin, außer Gebrauch kommen Mit dem Array werden alle überlebenden Daten in einer zusammenhängenden Reihe von Zeilen (am Anfang des Blocks) gehalten. Es scheint eine Verschwendung zu sein, an all dem RAM festzuhalten, wenn ich es wirklich nicht brauche.
Während ich weiß, dass realloc() verwendet werden kann, um dynamisch erstellte Arrays zu verkleinern, ist ein 2D-Array komplexer. Ich denke, ich verstehe das Speicherlayout davon (da ich die Funktion implementiert habe, die es strukturiert), aber dies treibt die Grenzen meines Verständnisses der Sprache und der Funktionsweise ihrer Compiler. Offensichtlich müsste ich mit Zeilen arbeiten (und mit den Zeilenzeigern umgehen), nicht nur Bytes, aber ich weiß nicht, wie vorhersehbar das Ergebnis von all dem sein würde.
Und ja, ich muss das Array mit einem einzigen malloc() erstellen. Das Objekt hat mehrere Millionen Zeilen. Ich habe versucht, eine Schleife zu malloc() jeder Zeile getrennt, aber das Programm immer um rund 100.000 malloc() s eingefroren.
für den Hintergrund, die Quelle ich diese Anordnung zu konstruieren bin ist wie folgt:
char ** alloc_2d_arr(int cnum, int rnum) {
/* ((bytes for row pointers + (bytes for data)) */
char **mtx = malloc(rnum * sizeof (char *) + rnum * cnum * sizeof (char));
/* Initialize each row pointer to the first cell of its row */
char *p = (char *) (mtx + rnum);
for (int i = 0; i < rnum; i++) {
mtx[i] = p + i * cnum;
}
return mtx;
}
'realloc' ist keine gute Idee für so große Tische, schauen Sie sich" avl "und" rot-schwarz "Bäume an. –
"Es scheint eine Verschwendung zu sein, an all dem RAM festzuhalten, wenn ich es wirklich nicht brauche." - Erstes * Profil *.Zweitens, ein Realloc läuft das hohe Risiko des Auslösens Kopieren all Ihrer Still-Interior-Daten auf verschiedene Seiten, die nicht trivialen Kosten, die Sie allein aus dem Grund zu versuchen, RAM zu speichern Sie selbst Anspruch ist nicht wirklich ein Problem. Das einzige Win-Szenario ist "Realloc", bei dem der Regionskopf als Speicherbasis beibehalten wird und die Endseiten für andere Zwecke zurückgegeben werden. etwas "Realloc" hat keine Garantien über ... – WhozCraig
... so haben Sie stattdessen nur 2 (oder 3 oder 4, was auch immer) Allokationen, denken Sie daran, welche Sie schließlich behalten, und 'free()' - diejenigen, die Sie nicht mehr brauchen, sobald dieses Ereignis eintritt? I.e. die "behalten" Hälfte Ihrer Matrix ist in der ersten Zuteilung, die zweite Hälfte ist in einer anderen Zuteilung, und schließlich befreien Sie einfach die zweite Hälfte. – WhozCraig