2010-07-06 8 views
2

je code suivantRedistribuer un tableau 2d char

int wordLenght = 256, arrayLength = 2, i = 0, counter = 0; 
char **stringArray = NULL; 

stringArray = calloc(arrayLength, sizeof(*stringArray)); 

for(counter; counter<wordLenght; counter++) 
    stringArray[counter] = calloc(wordLenght, sizeof(stringArray)); 

while(1) 
{ 
    printf("Input: "); 
    fgets(stringArray[i], wordLenght, stdin); 

    printf("stringArray[%d]: %s\n", i, stringArray[i]); 

    if(i == arrayLength) 
    { 
    printf("Reallocation !!!\n"); 
    arrayLength *= 2; 

    stringArray = realloc(stringArray, arrayLength*sizeof(*stringArray)); 

    } 

    i++; 
}  

Je reçois cette erreur de réaffectation:

*** glibc detected *** ./stringArray: realloc(): invalid next size: 0x0000000000b49010 *** 
======= Backtrace: ========= 
/lib/libc.so.6(+0x775b6)[0x7f4dd12565b6] 
/lib/libc.so.6(+0x7dd66)[0x7f4dd125cd66] 
/lib/libc.so.6(realloc+0xf0)[0x7f4dd125d080] 
./stringArray[0x4007f9] 
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f4dd11fdc4d] 
./stringArray[0x400629] 

Quel est mon problème ici ???

Merci, salue

Répondre

2
stringArray = calloc(arrayLength, sizeof(*stringArray)); 

Ici vous vouliez probablement utiliser sizeof (char *)

for(counter; counter<wordLenght; counter++) stringArray[counter] = calloc(wordLenght, sizeof(stringArray)); 

Ici vous Looping 256 fois (wordLenght), mais vous devez seulement 2 fois (arrayLength). De plus, vous vouliez probablement utiliser sizeof (char) au lieu de sizeof (stringArray). Cette vérification doit être effectuée avant d'appeler fgets, car vous utilisez d'abord la mémoire pour l'allouer ensuite.

De plus après avoir réallouer stringArray vous devez allouer reste de chaînes en utilisant quelque chose comme ça

for(counter = i; counter<arrayLength; counter++) stringArray[counter] = (char*)calloc(wordLenght, sizeof(char)); 

Et enfin, vous devez libérer toute la mémoire allouée avant de quitter l'application.

+0

+1 car j'ai raté le (i == arrayLength) –

+0

Merci beaucoup! Maintenant ça marche bien ;-) – leon22

+0

Puis marquez-le comme la réponse et merci pour la question :) –

2

Vous avez probablement ne veut pas dire sizeof(*stringArray)

En fait, je crois que vous pouvez relooker à l'appel calloc aussi, je pense que vous allouez la taille du pointeur là (mot longueur fois).

+0

Une allocation par ligne est une manière horrible de créer un tableau multidimensionnel. Vous devez l'allouer en un seul bloc et effectuer vous-même l'arithmétique de décalage (toujours possible) ou déclarer un type de pointeur de tableau de longueur variable approprié (C99 uniquement). –

+1

Il voulait probablement dire sizeof (* stringArray). stringArray est un tableau de pointeurs sur char, et c'est ce qui est en train d'être doublé à chaque fois qu'il manque d'espace. Mais vous avez raison sur le 'stringArray [compteur] = calloc (wordLenght, sizeof (stringArray));' appels. –

0

Après la première fois cette ligne exécute:

stringArray = realloc(stringArray, arrayLength*sizeof(*stringArray)); 

puis stringArray [arrayLength/2] sera une valeur de déchets - ne définissez pas au point de stockage pour le mot.

Cette partie doit utiliser soit utiliser sizeof (** stringArray), ou 1 ** stringArray est char, et le compteur ne doit aller jusqu'à arrayLength:

for(counter; counter<wordLenght; counter++) 
    stringArray[counter] = calloc(wordLenght, sizeof(stringArray)); 

allouent lieu dans un bloc:

char* block = malloc(wordLength * arrayLength); 

for (counter; counter < arrayLength; ++counter) 
    stringArray[counter] = block + (counter * wordLength); 

À l'heure actuelle, il est possible qu'il y ait un peu d'espace après stringArray, dans lequel vous stockez le (-arrayLength longueur de mot) pointeurs supplémentaires lorsque vous les calloc, et realloc ne bouge pas stringArray.

Il est tout à fait probable que 0xb49010 est l'un des pointeurs vous calloc'd, et vous êtes écrasé la mémoire où malloc conserve sa taille de bloc ..

Mais puisque vous écrivez de la fin de stringArray, vous êtes dans un comportement indéfini de toute façon.

0

Ok ici est la solution tout:

int wordLength = 256, arrayLength = 2, i = 0, counter = 0; 
    char **stringArray = NULL; 
    char buffer[wordLength]; 

    stringArray = calloc(arrayLength, sizeof(char*)); 
    for(counter; counter<arrayLength; counter++) stringArray[counter] = (char*)calloc(wordLength, sizeof(char)); 

    while(1) 
    { 
     if(i == arrayLength) 
     { 
      printf("Reallocation !!!\n"); 
      arrayLength *= 2; 

      stringArray = realloc(stringArray, arrayLength*sizeof(char*)); 
      for(counter = i; counter<arrayLength; counter++) stringArray[counter] = (char*)calloc(wordLength, sizeof(char)); 
     } 

     printf("Input: "); 
     fgets(buffer, wordLength, stdin); 

     if(!strcmp(buffer,"q\n")) break; // also free here  
     else stringArray[i] = buffer; 

     printf("stringArray[%d]: %s\n", i, stringArray[i]); 

     i++; 
    } 

Comment est la meilleure façon de libérer l'espace?!