在C中扩展动态char **数组时,realloc()失败

时间:2016-07-19 18:02:43

标签: c arrays memory dynamic realloc

我正在编写一个脚本,需要将非常大的文件(110,000L)中的每一行读入动态数组(然后它会执行与我的问题无关的事情)。这是相关代码:

 FILE *orig;
 FILE *dest;
    orig = fopen("../../dicts/mpron/pronDict.txt","r+");
    dest = fopen("../../dicts/editedPronDict.txt","w");

    char **arr = malloc(sizeof(char *)*128);
    int size = 0;
    int capacity = 128;

    char *inputLine = malloc(sizeof(char)*128);
    fgets(inputLine,128,orig);

    while(!feof(orig)){

            arr[size] = malloc(sizeof(char)*128);
            strcpy(arr[size],inputLine);
            size++;

            if(size == capacity){
                    realloc(arr,sizeof(char *)*(capacity*2));
                    capacity*=2;
                    fprintf(stderr,"New size: %i\n",capacity);
            }
    }

这是非常基本的东西,我认为它会完美运行。但是,我得到了这个输出:

./organizeMpron
New size: 256
New size: 512
organizeMpron(2088,0x7fff7c53e300) malloc: *** error for object  
0x7fc2aa001200: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug  
Abort trap: 6

所以它在崩溃之前只增加了两倍的容量。我尝试将数组的初始容量更改为64,奇怪的是我得到了完全不同的输出:

./organizeMpron
New size: 128
New size: 256
New size: 512
New size: 1024
New size: 2048
New size: 4096
New size: 8192
New size: 16384
New size: 32768
New size: 65536
New size: 131072
Segmentation fault: 11

有没有人知道这里会发生什么?我已经多次以这种方式编写动态集合,我不知道这段代码在哪里破解。提前谢谢。

1 个答案:

答案 0 :(得分:4)

realloc(arr,sizeof(char *)*(capacity*2));

可能会重新分配arr,但它不会更改arr的值,该值仍然指向(现已解除分配的)原始块。你可能意味着

arr = realloc(arr,sizeof(char *)*(capacity*2));

尽管在重新分配失败的情况下会出现内存泄漏。

有关详细信息,请参阅realloc manpage

为每一行分配128个字节似乎有点傻,除非您认为所有行都是相同的长度。您可以只分配线路所需的字节数(加上终止NUL)。 (或者您可以将所有行读入一个连续的内存区域,然后使用类似strtok的内容来分割所有换行符并构建您的数组,这样会更高效,但这样做超出范围。)

或者,如果你要为每一行分配一个固定的缓冲区大小而不管它有多长,那么就没有必要读入临时缓冲区,然后将临时缓冲区复制到数组中。只需直接读入相应的数组缓冲区即可。

最后,while (!feof(f)) is almost always wrong.