Перераспределить массив двумерных символов - PullRequest
2 голосов
/ 06 июля 2010

У меня следующий код

 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++;
 }    

Я получаю эту ошибку перераспределения:

*** 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]

В чем моя проблема здесь?

Спасибо, привет

Ответы [ 4 ]

2 голосов
/ 06 июля 2010
 stringArray = calloc(arrayLength, sizeof(*stringArray));

Здесь вы, вероятно, хотели использовать sizeof (char *)

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

Здесь вы зацикливаетесь 256 раз (wordLenght), но вам следует только 2 раза (arrayLength). Кроме того, вы, вероятно, хотели бы использовать sizeof (char) вместо sizeof (stringArray).

if(i == arrayLength) {...}

Эта проверка должна быть выполнена до того, как вы вызовете fgets, потому что сейчас вы сначала используете память, а затем выделяете их.

Кроме того, после перераспределения stringArray вам нужно выделить остальные строки, используя что-то вроде этого

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

И, наконец, вам необходимо освободить всю выделенную память перед выходом из приложения.

2 голосов
/ 06 июля 2010

Вы, вероятно, не имели в виду sizeof(*stringArray)

На самом деле, я полагаю, что вы, возможно, захотите пересмотреть вызов calloc, я думаю, что вы выделяете размер указателя там (длина слова раз).

0 голосов
/ 06 июля 2010

Хорошо, вот и все решение:

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++;
    }

Как лучше всего освободить пространство?!

0 голосов
/ 06 июля 2010

После первого выполнения этой строки:

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

, тогда stringArray [arrayLength / 2] будет значением мусора - вы не установили его, чтобы он указывал на хранилище для слова.

Эта часть должна использовать либо sizeof (** stringArray), либо 1, так как ** stringArray is char, а счетчик должен идти только до arrayLength:

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

Вместо этого выделять водин блок:

 char* block = malloc(wordLength * arrayLength);

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

В настоящий момент, возможно, после stringArray есть некоторое пространство, в которое вы сохраняете (wordLength-arrayLength) дополнительные указатели при их вызове, и realloc не перемещаетсяStringArray.

Вполне вероятно, что 0xb49010 является одним из указателей, которые вы называете calloc'd, и вы перезаписываете память, в которой malloc сохраняет размер блока ..

Но так как вы списываетеконец stringArray, вы все равно будете в неопределенном поведении.

...