c - 当输入数据超出原始分配空间时,C 中更好的内存分配方法是什么?

标签 c allocation

我知道C中有一个通用的策略来处理输入数据(例如文本)超出原始分配空间的情况。这就是重新分配更多空间。

#include <stdlib.h>
#include <stdio.h>

#define BUF_SIZE 1024

void check_buffer(char *buffer) 
{
    if (!buffer) {
        fprintf(stderr, "lsh: allocation error\n");
        exit(EXIT_FAILURE);
    }
}

char *read_line() 
{
    int bufsize = BUF_SIZE;
    int position = 0;
    char *buffer = malloc(sizeof(char) * bufsize);
    int c;

    check_buffer(buffer);

    while (1) {
        c = getchar();

        if (c == EOF || c == '\n') {
            buffer[position] = '\0';
            return buffer;
        } else {
            buffer[position] = c;
        }
        position++;

        if (position >= bufsize) {
            bufsize += BUF_SIZE; // Or `bufsize *= 2;`?
            buffer = realloc(buffer, bufsize);

            check_buffer(buffer);
        }
    }
}

那么有什么更好的方式来扩展原有的空间呢? bufsize += BUF_SIZEbufsize *= 2 ?哪种方式更有效?

最佳答案

Which way is more effective?

这是一个非常模糊的问题。对什么方面有效?请注意,“性能”并不是一个好的答案,因为它几乎与“有效”一样含糊不清。

你不能说一种方法比另一种更好。两者各有利弊,很大程度上取决于实际情况和BUF_SIZE的值。

选择其中之一。如果您遇到性能问题,请尝试其他方法并尝试调整 BUF_SIZE 的值。但在执行此操作之前,请分析代码以查看重新分配是否确实是问题所在。

第三种选择介于两者之间。你可以这样做:

bufsize = bufsize*log(bufsize);
realloc(buffer, bufsize);

第四种方法是使用指数增长直到达到阈值,然后切换:

if(bufsize > THRESHOLD)
    bufsize += LINEAR_INCREASE;
else
    bufsize *= 2;

纯指数增长可能导致问题的一种情况是,如果您已经拥有非常大的缓冲区。那么下次重新分配可能会失败,或者导致其他问题。

此外,请记住通过检查返回指针是否为 NULL 来检查重新重新分配(以及初始分配)是否确实有效。并且永远不要将缓冲区分配给返回值。如果重新分配失败,您也会失去当前的分配。你可以这样做:

void * ptr = realloc(buffer, bufsize);
if(ptr) buffer = ptr;
else { // Handle the fact that reallocation failed }

如果您的内存量非常有限,那么执行以下操作可能是个好主意:

int increase = LINEAR_INCREASE;
void * ptr;
do {
    ptr = realloc(buffer, increase);
    increase /= 2; // If realloc failed, try with half the increase
} while(!ptr && increase > 0)
if(ptr) buffer = ptr;
else { /* Handle the fact that reallocation failed */ }

关于c - 当输入数据超出原始分配空间时,C 中更好的内存分配方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53847876/

相关文章:

C 相当于 c++ cin.peek()

c - 在 imagemagick 中使用 C API 将图像保存在内存中而不是磁盘中?

c++ - 带有 std::vector 的自定义解除分配器不会被调用

c - 使用动态内存分配在二维数组中添加值

c++ - 你能在 OpenGL 中获得为纹理分配的内存吗?

c++ - 搜索可使用自定义 gcc 安装的适用于 OS X 的 C/C++ IDE

c - 这个简单的 If 语句有什么作用?

python - 将 Python 对象放在共享内存中

c - 动态地为可变大小的结构数组分配空间

c++ - 在静态库中包含静态库 - CodeBlocks