额外的文件访问权限或大量的realloc

时间:2014-07-23 20:06:52

标签: c memory-management file-io

我正在编写一个需要逐行解析配置文件的函数。

我基本上有3种方法可以从这里开始,我正处于将内容读入内存的阶段:

  1. 读取一行中的字符数量,fseek()返回行首,malloc()缓冲区,将行读入内存

  2. 读取行中的字符,并为每个添加字符读取realloc()

  3. 做出猜测'合理的行长度,一旦超过,则仅realloc()

  4. 时间在这个阶段并不重要,所以1ms或半秒是不是真的重要,但我希望得到最好的解决方案。

    过去我使用过解决方案1,因为我并不是真的想调用realloc()几百次。

    什么是最佳做法?

    E /

    进一步解释:

    我的配置文件看起来像这样

    key = value #comment

    我在阅读时将=字符替换为\0字符并跟踪偏移量。然后我strcompare()我要查找的行到配置标记,一旦找到匹配的配置标记,我将值移动到数组的开头并进行后处理(atoi(),{{1那些东西)并把它放到另一个变量中。之后,我释放了我的读取线并转到下一行。

    当我读字符的时候我就这样做了。在strtoull()不被读入内存之后,我会跳过空格和所有内容。所以我的整个key = value字符串在99%的情况下都是<64字节。

3 个答案:

答案 0 :(得分:2)

不是分配小缓冲区并经常重新分配,而是分配一个大缓冲区并重新分配到所需的确切大小。也许这样的事情会起作用吗?

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

char *getinput ( ) {
    char *input;

    input = malloc ( 1000); // allocate a large buffer
    fgets (input, 1000, stdin);
    // may need to set a '\0' somewhere in input...
    input = realloc ( input, strlen(input) + 1); // realloc to exact size
    return input;
}

int main()
{
    char *output[10];
    int counter = 0;

    while ( counter < 10) {
        output[counter] = getinput();
        printf ( "%s\n", output[counter]);
        counter++;
    }
    counter = 0;
    while ( counter < 10) {
        printf ( "\t%s\n", output[counter]);
        free ( output[counter]);
        counter++;
    }
    return 0;
}

答案 1 :(得分:1)

当输入数据的大小变大时,我使用类似于Exponential Backoff的技术。

近似算法是:

  1. 分配一个小缓冲区
  2. 在缓冲区中有一些空间时读取数据
  3. 如果缓冲区已满并且有一些数据需要读取,请将缓冲区大小加倍(通过realloc()
  4. 转到第2步
  5. 如果您一次读取整个文件,则只需将所有传入数据附加到缓冲区的末尾。

    如果您一次只读一行,请在循环中使用fgets(),如下所示:

    1. 分配缓冲区
    2. 设置buffer[size - 1] = 0xFF;
    3. fgets(buffer, size, fp);
    4. if buffer[size - 1] == '\0'然后缓冲区已满,realloc()它并转到第2步
    5. 当您希望获得任意大行时,这种方法是明智的,例如,有人会决定将一些base64编码的数据放入配置文件中。如果不是这种情况,我通常会尽量保持简单:

      1. 分配一个可能适合文件中任何一行的固定大小的缓冲区
      2. 尝试读取一行,如果它不适合缓冲区,则abort()
      3. 事实上,这种方法往往比任何缓冲区重新分配产生更少的错误,KISS的美丽。

答案 2 :(得分:0)

我会做以下事情:

首先将整个文件读入缓冲区,只需先检查大小即可。 stat()然后全部读完。

将整个文件内容放入缓冲区后,您可以根据自己的内容进行操作。