释放动态分配的2D结构

时间:2011-07-19 21:56:43

标签: c dynamic-allocation

我动态分配了一个结构,在概念上非常类似于矩阵,用于保存一组字符串。我在尝试释放内存时遇到了问题。我的代码如下所示:

# include <stdio.h> 
# include <string.h>
# include <malloc.h>
# define SIZE 2

typedef struct fork{
char** dataPointersArray;
char*  dataArray;
}fork;

int main(int argc, char* argv[]){

fork forkDS;
int i;
char* dataArrayPtr;
unsigned char data[255] = "some data"; /* this is actually a function's output */
int PtrIndex;

/* allocate memory for the arrays */
    forkDS.dataPointersArray = (char**) calloc(SIZE ,sizeof(char*));

    if(forkDS.dataPointersArray == NULL){
        printf("couldn't allocate memory \n");

    }

    forkDS.dataArray = (char*) calloc(SIZE, 255);

    if( forkDS.dataArray == NULL){
        free(forkDS.dataPointersArray);
        printf("couldn't allocate memory \n");

    }
    dataArrayPtr = forkDS.dataArray;
    for(i = 0; i < SIZE; i++){
    /* update the dataPointers Array */
        forkDS.dataPointersArray[i] = dataArrayPtr;


        /* copy data into data array */
        memcpy(dataArrayPtr,data,20);

        dataArrayPtr[255] = '\0';

        /* update the pointer of the data array */
        dataArrayPtr = dataArrayPtr + 256;
    }


    for (PtrIndex = 0; PtrIndex < 2; PtrIndex++) {
        if (*(forkDS.dataPointersArray + PtrIndex) != NULL) {
            *(forkDS.dataPointersArray + PtrIndex) = NULL;
        }
    }

    /* DEBUG comment -  this 2 lines works */
    free(forkDS.dataArray); 
    forkDS.dataArray = NULL;

    /* DEBUG comment - the next line fails */
    free(forkDS.dataPointersArray);
    forkDS.dataPointersArray = NULL;


return 0;
}

因此,该结构实际​​上包含2个数组,一个指向字符串的指针,另一个包含一个接一个地对齐的字符串,由终止\ 0分隔。

代码工作正常,最后的for循环也可以。第一次免费电话也有效。问题是最后一次免费通话失败了。 虽然尝试搜索关于该问题的所有可能数据,但我发现的所有示例都考虑了这样的情况:第二个数组(包含字符串)在for循环中逐步分配,然后在for循环中释放。

我想避免在循环中使用动态分配,因此我的代码看起来不同。

有谁知道问题是什么?

=============================================== =======================================

非常感谢所有回答我的人。最终,错误得到了解决。问题是dataPointersArray在其他一些代码中填充了多个SIZE元素,这些代码起初似乎是无辜的,实际上导致了免费调用失败。

再次感谢您的评论! Shachar

2 个答案:

答案 0 :(得分:6)

您正在分配SIZE * 255个字节,但使用SIZE * 256个字节:

forkDS.dataArray = (char*) calloc(SIZE, 255); 
dataArrayPtr = forkDS.dataArray;   

//SIZE TIMES loop:
    dataArrayPtr = dataArrayPtr + 256; 

因此,当您对指针进行NULL操作时,您可能会覆盖自由寻找的malloc覆盖数组末尾的控制数据。

答案 1 :(得分:0)

您为包含SIZE行的数组分配了空间,每行包含255个字符。因此,每行的最高索引是254 = 255 - 1.当您编写\ 0字符时,您将在下一行的开头写入它。在最后一次迭代之后,你将被SIZE字节关闭。

另一个细节:如果任何内存分配失败,程序将只打印其错误消息,但它不会在以后停止导致SEGFAULT。