2010-07-06 41 views
2

我有下面的代码重新分配一个二维字符数组

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] 

什么这里是我的问题???

谢谢,迎接

回答

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

在这里,你可能想使用sizeof(字符*)

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

在这里,你是循环256次(wordLenght),但你应该只有2次(arrayLength)。此外,您可能想使用sizeof(char)而不是sizeof(stringArray)。

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

这个检查应该在你调用fgets之前完成,因为你现在先使用内存然后再分配它们。

此外,您重新分配字符串数组后,您需要分配使用的东西串的其余部分是这样

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

最后,你需要释放所有分配的内存退出应用程序之前。

+0

+1因为我错过了(i == arrayLength) – 2010-07-06 13:45:30

+0

非常感谢!现在它工作正常;-) – leon22 2010-07-06 15:44:36

+0

然后将其标记为答案,并感谢您的问题:) – 2010-07-06 18:17:14

2

你可能并不意味着sizeof(*stringArray)

事实上,我相信你可能想在calloc呼吁重新审视过,我觉得你有分配指针的大小(字长度时间)。

+0

每行一次分配是制作多维数组的一种可怕方法。您应该将其分配为一个块,并自己执行偏移量算法(始终可能),或者声明适当的可变长度数组指针类型(仅限C99)。 – 2010-07-06 13:17:35

+1

他可能确实意味着sizeof(* stringArray)。 stringArray是一个指向char的指针数组,这就是每次空间耗尽时扩大到两倍大小的内容。但是你对'stringArray [counter] = calloc(wordLenght,sizeof(stringArray));''调用。 – 2010-07-06 13:31:39

0

后的第一次此行执行:

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

然后字符串数组[arrayLength/2]将是一个垃圾值 - 你没有把它设置为指向存储的单词。

这部分应该使用使用sizeof(**字符串数组),或1作为**字符串数组是炭,并且计数器只应上去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); 

目前,它可能是有字符串数组后一些空间,要在其中存储(字长-arrayLength)额外的指针,当你释放calloc他们和realloc不动字符串数组。

这是很可能的0xb49010是你calloc'd的指针之一,而你在那里覆盖的malloc保持其块大小的内存..

但是既然你注销字符串数组的结束,无论如何,你都陷入了未定义的行为。

0

确定这里是整个解决方案:

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

是如何释放空间的最佳方式!