在 C 中扩展动态 char** 数组时 realloc() 失败
realloc() fail when expanding dynamic char** array in C
我正在编写一个脚本,需要将一个非常大的文件 (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
有人知道这里发生了什么吗?我已经多次以这种方式编写动态集合,但我不知道这段代码在哪里出错。提前谢谢你。
realloc(arr,sizeof(char *)*(capacity*2));
可能会重新分配 arr
,但它不会更改 arr
的值,它仍然指向(现已解除分配的)原始块。你可能是说
arr = realloc(arr,sizeof(char *)*(capacity*2));
尽管在重新分配失败的情况下会发生内存泄漏。
为每一行分配 128 个字节似乎有点傻,除非你相信所有的行都是相同的长度。您可以只分配该行所需的字节数(加上一个终止 NUL)。 (或者您可以将所有行读入一个连续的内存区域,然后使用 strtok
之类的东西来拆分所有换行符并构造您的数组,这会更有效率,但这超出了范围。 )
或者,如果您要为每一行分配一个固定的缓冲区大小,而不管它有多长,那么读入临时缓冲区然后将临时缓冲区复制到数组中是没有意义的。直接读入适当的数组缓冲区即可。
最后,while (!feof(f))
is almost always wrong.
我正在编写一个脚本,需要将一个非常大的文件 (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
有人知道这里发生了什么吗?我已经多次以这种方式编写动态集合,但我不知道这段代码在哪里出错。提前谢谢你。
realloc(arr,sizeof(char *)*(capacity*2));
可能会重新分配 arr
,但它不会更改 arr
的值,它仍然指向(现已解除分配的)原始块。你可能是说
arr = realloc(arr,sizeof(char *)*(capacity*2));
尽管在重新分配失败的情况下会发生内存泄漏。
为每一行分配 128 个字节似乎有点傻,除非你相信所有的行都是相同的长度。您可以只分配该行所需的字节数(加上一个终止 NUL)。 (或者您可以将所有行读入一个连续的内存区域,然后使用 strtok
之类的东西来拆分所有换行符并构造您的数组,这会更有效率,但这超出了范围。 )
或者,如果您要为每一行分配一个固定的缓冲区大小,而不管它有多长,那么读入临时缓冲区然后将临时缓冲区复制到数组中是没有意义的。直接读入适当的数组缓冲区即可。
最后,while (!feof(f))
is almost always wrong.