【问题标题】:Reallocate a 2d char array重新分配一个二维字符数组
【发布时间】:2011-03-12 07:20:56
【问题描述】:

我有以下代码

 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]

我有什么问题???

谢谢,问候

【问题讨论】:

    标签: c char multidimensional-array realloc


    【解决方案1】:

    好的,这是整个解决方案:

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

    释放空间的最佳方法是什么?!

    【讨论】:

      【解决方案2】:

      这行第一次执行后:

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

      那么 stringArray[arrayLength/2] 将是一个垃圾值 - 你还没有将它设置为指向单词的存储空间。

      这部分应该使用 sizeof(**stringArray),或者 1,因为 **stringArray 是 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 是您调用的指针之一,并且您被覆盖了 malloc 保持其块大小的内存..

      但是由于您正在注销 stringArray 的末尾,所以无论如何您都会陷入未定义的行为。

      【讨论】:

        【解决方案3】:
         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));
        

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

        【讨论】:

        • sizeof(*stringArray) 没有问题(虽然第二个应该是sizeof(**stringArray))——其实这种风格应该是首选。我倾向于将它们分别写为sizeof stringArray[0]sizeof stringArray[0][0]
        • 释放已分配内存的最佳方法是什么?
        【解决方案4】:

        你可能不是说sizeof(*stringArray)

        事实上,我相信您可能也想重新查看 calloc 调用,我认为您正在那里分配指针的大小(字长时间)。

        【讨论】:

        • 每行分配一次是创建多维数组的可怕方式。您应该将其分配为一个块,然后自己进行偏移算术(总是可能的),或者声明一个适当的可变长度数组指针类型(仅限 C99)。
        • 他的意思可能是 sizeof(*stringArray)。 stringArray 是一个指向 char 的指针数组,每次空间不足时,它的大小都会扩大到两倍。但是您对 'stringArray[counter] = calloc(wordLenght, sizeof(stringArray));' 是对的来电。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-31
        • 1970-01-01
        • 2015-06-23
        • 2021-10-11
        • 2012-03-27
        相关资源
        最近更新 更多