我正在编写一个脚本,需要将非常大的文件(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
有没有人知道这里会发生什么?我已经多次以这种方式编写动态集合,我不知道这段代码在哪里破解。提前谢谢。
答案 0 :(得分:4)
realloc(arr,sizeof(char *)*(capacity*2));
可能会重新分配arr
,但它不会更改arr
的值,该值仍然指向(现已解除分配的)原始块。你可能意味着
arr = realloc(arr,sizeof(char *)*(capacity*2));
尽管在重新分配失败的情况下会出现内存泄漏。
有关详细信息,请参阅realloc manpage
为每一行分配128个字节似乎有点傻,除非您认为所有行都是相同的长度。您可以只分配线路所需的字节数(加上终止NUL)。 (或者您可以将所有行读入一个连续的内存区域,然后使用类似strtok
的内容来分割所有换行符并构建您的数组,这样会更高效,但这样做超出范围。)
或者,如果你要为每一行分配一个固定的缓冲区大小而不管它有多长,那么就没有必要读入临时缓冲区,然后将临时缓冲区复制到数组中。只需直接读入相应的数组缓冲区即可。