为什么使用4096个元素作为char数组缓冲区?

时间:2014-02-27 05:55:09

标签: c buffer

我找到了一个接受标准输入的程序

int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <PATTERN>\n", argv[0]);
        return 2;
    }

    /* we're not going to worry about long lines */
    char buf[4096]; // 4kibi

    while (!feof(stdin) && !ferror(stdin)) { // when given a file through input redirection, file becomes stdin
        if (!fgets(buf, sizeof(buf), stdin)) { // puts reads sizeof(buf) characters from stdin and puts it into buf; fgets() stops reading when the newline is read
            break;
        }
        if (rgrep_matches(buf, argv[1])) {
            fputs(buf, stdout); // writes the string into stdout
            fflush(stdout);
        }
    }

    if (ferror(stdin)) {
        perror(argv[0]); // interprets error
        return 1;
    }

    return 0;
}

为什么buf设置为4096个元素?是因为每行的最大字符数只能是4096?

5 个答案:

答案 0 :(得分:2)

该程序每次迭代只读取4096个字符。

行的大小没有限制,但可能是堆栈大小的限制(现代linux系统中为8 MB)

大多数程序员选择最适合所实施程序的程序员,在这种情况下,程序员评论说不需要担心更长的行。

答案 1 :(得分:2)

答案在您粘贴的代码中:

/* we're not going to worry about long lines */
char buf[4096]; // 4kibi

可能会出现超过4096个字符的行,但作者并不认为值得关注。

还请注意fgets的定义:

  

fgets()从流中读取最多一个小于大小的字符,并将它们存储到s指向的缓冲区中。读数在EOF或换行符后停止。如果读取换行符,则将其存储到缓冲区中。终止空字节(\0)存储在缓冲区中的最后一个字符之后。

因此,如果有一个超过4095个字符的行(因为4096&#39;是为空字节保留的),它将被分割为while循环的多次迭代。

答案 2 :(得分:1)

作者似乎只有一个非常大的内存块用于他的预期输入,以避免处理块。

看似笨拙的数字4096很可能是因为它是a)两个数的幂而b)是一个内存页面大小。因此,当系统选择将页面换成光盘时,它可以一次性完成,而不会产生任何开销。

这真的有帮助是另一个问题,因为如果您使用'malloc'分配页面,它可能不会在页面边界上对齐。

我自己也经常使用这样的数字,因为它没有伤害,在最好的情况下它可能有所帮助。但是,如果您担心速度并且您已经详细地重新分配了分配过程,那么它才真正有用。如果直接从操作系统分配页面,那么这样的大小可能确实有一些好处。

答案 3 :(得分:1)

行中没有最多没有字符的东西。假设正常情况下4096是没有线将超过4096字节。

更像是为最坏的情况做准备。

假设您将数组的大小小于sizeof(行),然后将操作分解为多个步骤,直到遇到eof。

答案 4 :(得分:0)

我认为这只是作者根据代码中的注释设计将char缓冲区大小选择为4 * kibi *(4096 = 1024 * 4)。