Sono principalmente interessato alla redditività di che termina come una matrice.L'uso di realloc() su un array 2D assegnato dinamicamente è una buona idea?
Sto lavorando a un progetto in cui ho utilizzato singole chiamate malloc() per creare singoli array 2D moderatamente grandi. (Ogni poche decine di MiB, al massimo.) La cosa è che nel corso della vita di uno degli array, il suo contenuto si riduce drasticamente in termini di dimensioni (di oltre la metà). Ovviamente, potrei lasciare la dimensione dell'array da solo per la vita del programma. (È solo un x MiB su un sistema con GiB di RAM disponibile.) Ma, stiamo parlando di più della metà dello spazio assegnato che cade in disuso ben prima che il programma termini, e, a causa della natura di come sono usando l'array, tutti i dati sopravvissuti vengono mantenuti in un insieme contiguo di righe (all'inizio del blocco). Sembra uno spreco tenere tutto il RAM se davvero non ne ho bisogno.
Mentre so che realloc() può essere utilizzato per ridurre gli array creati dinamicamente, un array 2D è più complesso. Penso di averne compreso il layout di memoria (dato che ho implementato la funzione che lo struttura), ma questo sta spingendo i limiti della mia comprensione della lingua e del funzionamento dei suoi compilatori. Ovviamente, dovrei lavorare con le righe (e gestire i puntatori di riga), non solo i byte, ma non so quanto sarebbe prevedibile l'esito di tutto ciò.
E, sì, ho bisogno di creare l'array con un singolo malloc(). L'oggetto in questione ha diverse milioni di righe. Ho provato ad usare un ciclo su malloc() ogni riga separatamente, ma il programma si bloccava sempre a circa 100.000 malloc() s.
per lo sfondo, la fonte che sto usando per costruire questi array è come segue:
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' non è una buona idea per tavoli così grandi, date un'occhiata agli alberi" avl "e" rosso-nero ". –
"Sembra davvero uno spreco tenere tutto su quella RAM se davvero non ne ho bisogno." - Primo * profilo *.In secondo luogo, un realloc corre il rischio elevato di attivare la copia di tutti i dati ancora interni in pagine diverse, la cui spesa non banale è dovuta esclusivamente al tentativo di salvare ram che tu stesso rivendichi non è un problema. L'unico scenario di vittoria qui è 'realloc' mantenendo la stessa region-head come base di memoria, e le pagine di coda restituite per altri usi; qualcosa di 'realloc' non ha garanzie su ... – WhozCraig
... quindi hai pensato di fare solo 2 (o 3 o 4, qualunque) allocazioni, ricorda quali sono quelle che stai mantenendo, e' free() '- quelli di cui non hai più bisogno una volta che l'evento si manifesta? Cioè la metà "mantenuta" della matrice è nella prima allocazione, la seconda metà è in un'altra allocazione e alla fine si libera solo la seconda metà. – WhozCraig