我有一个关于动态内存分配的问题。
上下文:我正在编写一个程序,该程序读取单词的文本文件并计算每个单词出现的频率(每行一个单词)。
这个特定的函数读取文件,计算行数和字符数,然后将内存动态分配给字符串指针数组,该数组存储每一行的字符数以及字符串本身。 (其他部分与我的问题不太直接相关)。
问题:如果空间不足,应该多久重新分配一次内存?我设置一个常量(“memstart”)来设置初始内存分配值。在下面的代码片段中,我为“memstart”的值上的每一行重新分配。如果重新分配一个更大的内存块而不是每次都将内存空间增加1个“变量类型”,程序会更快吗?
这样的最佳做法是什么?
代码段:
int read_alloc(FILE* fin, FILE *tmp, char **wdp, int *sz){
int line_cnt= 0, chr, let=1;
do{
chr=getc(fin);
let++;
//count characters
if(chr!=EOF){
chr=tolower(chr);
fputc(chr, tmp);
}
//convert to lcase and write to temp file
if ('\n' == chr || chr==EOF){
sz[(line_cnt)]=((let)*sizeof(char)); //save size needed to store string in array
*(wdp+(line_cnt))=malloc((let)*sizeof(char)); //allocate space for the string
if ((line_cnt-1) >= memstart){
realloc(wdp, (sizeof(wdp)*(memstart+line_cnt))); //if more space needed increase size
realloc(sz, (sizeof(sz)*(memstart+line_cnt)));
}
line_cnt++;
let=1;
}
} while (EOF != chr);
return (line_cnt);
}
最佳答案
尽管问题在于应该多久调用一次realloc
,再看一下OP的代码,但我认为最好从安全性上着手。
C11标准规定(n1570草案,§7.22.3.5 ,realloc函数,重点是我的):
现在让我们考虑问题中的这段代码,其中sz
声明为int* sz;
realloc(sz, (sizeof(sz)*(memstart+line_cnt)));
返回值丢失,因此我们无法知道调用是否成功,如果成功,则
sz
无效。此外,sizeof(sz)
是指针的大小,而不是指针类型(int
)。更安全(且正确)的模式是:
size_t new_size = /* Whatever, let's say */ size + SOME_COSTANT + size / 2;
void *tmp = realloc(ptr, new_size * sizeof *ptr);
if ( tmp == NULL ) {
/* Deal with the error, e.g. log a message with perror, return NULL
(if this is in a function) or just give up, but remeber that
realloc doesn't invalidate nor free 'ptr' on failure */
exit(EXIT_FAILURE);
}
ptr = tmp; // <- on success, realloc invalidated ptr
size = new_size;
现在,为了回答这个问题,应仅在需要时才调用
realloc
,因为它涉及潜在的扩展系统调用。因此,要么提前分配大量资金,要么选择不断增长的战略,例如每次将规模扩大一倍(或1.5倍)。值得注意的是,如果可能,操作系统可以执行重新分配而无需复制原始数组的任何元素。