2013-09-28 23 views
18

Sto cercando di scrivere un programma che legge una serie di stringhe da un file di testo e li memorizza in una serie di stringhe, allocando dinamicamente la memoria per ciascun elemento. Il mio piano era quello di memorizzare ogni stringa in un array usando un puntatore e quindi far crescere le dimensioni dell'array man mano che altri elementi venivano letti. Ho difficoltà a capire perché il mio codice di test qui sotto non funziona. È un'idea praticabile?Allocazione memoria dinamica per array di puntatori

char *aPtr; 
aPtr =(char*)malloc(sizeof(char)); 

aPtr[0]="This is a test"; 


printf("%s",aPtr[0]); 
+1

Questo non funziona perché tu hai lo spazio 'malloc' per un singolo carattere, e poi provi ad assegnare un'intera stringa ad un lvalue' char'-tipizzato. –

+0

Lettura consigliata: [Quando dovrei usare malloc in C e quando non lo faccio?] (Http://stackoverflow.com/a/1963812/2455888). – haccks

risposta

15

In C una stringa è un char*. Una matrice dinamica di tipo T è rappresentata come un puntatore a T, quindi per char* sarebbe char**, non semplicemente uno char* il modo in cui è stato dichiarato.

Il compilatore, senza dubbio, ha emesso alcuni avvertimenti a riguardo. Presta attenzione a questi avvertimenti, molto spesso ti aiutano a capire cosa fare.

Ecco come si può iniziare la sperimentazione:

char **aPtr; 
int len = 1; // Start with 1 string 
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C 
aPtr[0] = "This is a test"; 
printf("%s",aPtr[0]); // This should work now. 
+0

Per verificare (si prega di sopportare con me, sono un novizio =]), se si desidera un array dinamico di puntatori per char (ad esempio, se necessario in un'applicazione in cui potrebbe essere necessario memorizzare stringhe di caratteri con numero variabile ad es., Da leggendo un file di testo senza conoscerne la lunghezza o raccogliendo l'input dell'utente di lunghezza non specificata), allora avresti bisogno di un array dinamico di Char * e quindi avresti bisogno di un Char **. Il carattere ** può puntare a diversi puntatori di caratteri, che possono essere l'indirizzo iniziale di diverse stringhe di caratteri. –

+0

a cosa serve il 'len = 1'? Sembra che "Questo è un test" sarebbe di 14 caratteri, che è un byte ciascuno .... ma questo codice non menziona 14, né segfault quando corro. – nmz787

+0

@ nmz787 Nota il tipo di 'aPtr', è un doppio puntatore, quindi rappresenta una matrice di puntatori di caratteri. Un puntatore char viene quindi impostato nell'elemento zero; nessuna copia di stringhe sta accadendo in questo codice. – dasblinkenlight

5
char * aPtr; 

è come puntatore a un carattere, a cui si allocata memoria per contenere esattamente 1 carattere.

Facendo

aPrt[0] = "test"; 

si indirizza la memoria per questo uno personaggi e cercare di memorizzare l'indirizzo del letterale "test" ad esso. Ciò fallirà poiché questo indirizzo è probabilmente più ampio di un personaggio.

Una correzione del codice sarebbe allocare memoria per un puntatore a un carattere.

char ** aPtr = malloc(sizeof(char *)); 
aPtr[0] = "test"; 
printf("%s", aPtr[0]); 

sono più eleganti e più nel corso valido approccio sarebbe quello di destinare lo stesso (così come l'aggiunta del controllo degli errori obbligatorio) facendo:

char ** aPtr = malloc(sizeof *aPtr); 
if (NULL == aPtr) 
{ 
    perror("malloc() failed"); 
    exit(EXIT_FAILURE); 
} 

... 
9
char *str; //single pointer 

Con questo si può memorizzare un stringa.


Per memorizzare array of strings che c'è two dimensional character array

oppure array of character pointers oppure double pointer


char str[10][50]; //two dimensional character array 

Se si dichiara in questo modo non è necessario allocare la memoria in quanto questa è la dichiarazione statica


char *str[10]; //array of pointers 

Qui è necessario allocare memoria per ogni puntatore

scorrere matrice per allocare memoria per ogni puntatore

for(i=0;i<10;i++) 
str[i]=malloc(SIZE); 

char **str; //double pointer 

Qui è necessario allocare memoria per Numero puntatori e quindi allocare memoria per ogni puntatore.

str=malloc(sizeof(char *)*10); 

E poi scorrere array di allocare memoria per ogni puntatore

for(i=0;i<10;i++) 
str[i]=malloc(SIZE); 
-1

Lo state facendo tutto sbagliato. La versione corretta del codice dovrebbe essere come questa:

int main() 
{ 
char *aPtr; 
aPtr =(char*)malloc(20*sizeof(char)); 
aPtr ="This is a test"; 
printf("%s",aPtr); 
} 

È possibile utilizzare la matrice di puntatori. se si desidera memorizzare più stringhe. Sì, lo so che usare per il ciclo sarà facile. Ma sto cercando di spiegare in modo semplice anche un principiante può capire.

int main() 
{ 
char *aPtr[10]; 
aPtr[0] =(char*)malloc(20*sizeof(char)); 
aPtr[0] ="This is a test"; 
aPtr[1] =(char*)malloc(20*sizeof(char)); 
aPtr[1] ="This is a test2"; 
printf("%s\n%s\n",aPtr[0],aPtr[1]); 
} 
+0

Il tuo primo esempio perde memoria, vale a dire 20 byte. Facendo 'aPtr =" Questo è un test ";' si perde il riferimento a ciò che 'malloc()' ha restituito. Questa memoria non è mai stata utilizzata e non verrà mai utilizzata durante il live del programma. – alk

+0

'sizeof (char)' è '1' è la definizione. Trasmettere il risultato di 'malloc/calloc/realloc' in non è necessario in C né consigliato: http://stackoverflow.com/a/605858/694576 – alk

+0

Grazie a tutti quelli che hanno risposto che è stato di grande aiuto – user2826534