我有一个关于动态内存分配的问题。

上下文:我正在编写一个程序,该程序读取单词的文本文件并计算每个单词出现的频率(每行一个单词)。

这个特定的函数读取文件,计算行数和字符数,然后将内存动态分配给字符串指针数组,该数组存储每一行​​的字符数以及字符串本身。 (其他部分与我的问题不太直接相关)。

问题:如果空间不足,应该多久重新分配一次内存?我设置一个常量(“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倍)。

值得注意的是,如果可能,操作系统可以执行重新分配而无需复制原始数组的任何元素。

09-10 04:19
查看更多