Domanda

Sto cercando di aggiungere altri 10 elementi alla mia struttura che è già malloc con una dimensione fissa di 20.Questo è il modo in cui ho definito la mia struttura:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct st_temp {
   char *prod;
};

int main ()
{
   struct st_temp **temp_struct;

   size_t j;
   temp_struct = malloc (sizeof *temp_struct * 20);
   for (j = 0; j < 20; j++) {
      temp_struct[j] = malloc (sizeof *temp_struct[j]);
      temp_struct[j]->prod = "foo";
   }

   return 0;
}

Quindi quello che avevo in mente era riallocare come (tuttavia, non so come fare):

temp_struct = (struct st_temp **) realloc (st_temp, 10 * sizeof(struct st_temp*));

e poi aggiungi i 10 elementi extra,

   for (j = 0; j < 10; j++)
      temp_struct[j]->prod = "some extra values";

Come potrei raggiungere questo obiettivo?Qualsiasi aiuto è apprezzato!

È stato utile?

Soluzione

Per evitare perdite di memoria, dobbiamo gestire la riallocazione con cura (ne parleremo più avanti).La funzione realloc:

void *realloc(void *ptr, size_t size), Dove

ptr = il puntatore all'originale (malloc'ndr) blocco di memoria, e

size = la nuova dimensione del blocco di memoria (in byte).

realloc restituisce la nuova posizione del blocco di memoria allocato dinamicamente (che potrebbe essere cambiato) - o NULL se la riallocazione non è riuscita! Se restituisce NULL, la memoria originale rimane invariata, quindi devi sempre usare una variabile temporanea per il valore restituito di realloc.

Un esempio chiarirà un po' questo (punti di interesse:La sintassi di realloc è simile a quella di malloc (non sono necessari cast aggiuntivi ecc.) e, dopo realloc, devi produrre gli stessi passaggi per i nuovi oggetti che hai fatto dopo malloc):

struct st_temp **temp_struct;
temp_struct = malloc(20 * sizeof *temp_struct);
if (temp_struct == NULL) { /* handle failed malloc */ }
for (int i = 0; i < 20; ++i) {
    temp_struct[i] = malloc(sizeof *temp_struct[i]);
    temp_struct[i]->prod = "foo";
}

// We need more space ... remember to use a temporary variable
struct st_temp **tmp;
tmp = realloc(temp_struct, 30 * sizeof *temp_struct);
if (tmp == NULL) { 
    // handle failed realloc, temp_struct is unchanged
} else {
    // everything went ok, update the original pointer (temp_struct)
    temp_struct = tmp; 
}
for (int i = 20; i < 30; ++i) { // notice the indexing, [20..30)
    // NOTICE: the realloc allocated more space for pointers
    // we still need to allocate space for each new object
    temp_struct[i] = malloc(sizeof *temp_struct[i]);
    temp_struct[i]->prod = "bar";
}
// temp_struct now "holds" 30 temp_struct objects
// ...
// and always do remember, in the end
for (int i = 0; i < 30; ++i)
    free(temp_struct[i]);
free(temp_struct);

Tieni presente che questo non è realmente un array di strutture, ma più un array di puntatori a strutture o anche un array di array di strutture, se lo desideri.Nell'ultimo caso, ogni sottoarray avrebbe lunghezza 1 (poiché allochiamo spazio solo per una struttura).

Altri suggerimenti

Quando si utilizza realloc(), è necessario dare al nuovo dimensioni al posto del numero di byte da aggiungere. Quindi:

temp_struct = (struct st_temp **) realloc (temp_struct, 30 * sizeof(struct st_temp*));

30 è, naturalmente, l'originale 20 più 10. La funzione realloc() si occupa di copiare i dati originali in una nuova posizione, se ha bisogno di spostare il blocco di memoria.

Poi, aggiungendo gli extra di 10 elementi sarebbe qualcosa di simile (a partire dall'indice 20, non 0):

for (j = 20; j < 30; j++) {
    temp_struct[j]->prod = "some extra values"; 
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top