这是一个大学任务的小程序:
#include <unistd.h>
#ifndef BUFFERSIZE
#define BUFFERSIZE 1
#endif
main()
{
char buffer[BUFFERSIZE];
int i;
int j = BUFFERSIZE;
i = read(0, buffer, BUFFERSIZE);
while (i>0)
{
write(1, buffer, i);
i = read(0, buffer, BUFFERSIZE);
}
return 0;
}
可以使用 stdio.h fread 和 fwrite 函数代替。
好。我用 25 个不同的缓冲区大小值编译了这两个版本的程序:1、2、4、...、2^i 和 i=0..30
这是我如何编译它的示例:gcc -DBUFERSIZE=8388608 prog_sys.c -o bin/psys.8M
问题:在我的机器上(Ubuntu Precise 64,最后有更多细节)所有版本的程序都可以正常工作:./psys.1M < data
(数据是一个带有 3 行 ascii 文本的小文件。)
问题是:当缓冲区大小为 8MB 或更大时。两个版本(使用系统调用或 clib 函数)都会因这些缓冲区大小而崩溃(分段错误)。
我测试了很多东西。代码的第一个版本是这样的: (...) main() { char buffer[BUFFERSIZE]; 诠释我;
i = read(0, buffer, BUFFERSIZE);
(...)
当我调用读取函数时,这会崩溃。但是对于这些版本:
main()
{
char buffer[BUFFERSIZE]; // SEGMENTATION FAULT HERE
int i;
int j = BUFFERSIZE;
i = read(0, buffer, BUFFERSIZE);
main()
{
int j = BUFFERSIZE; // SEGMENTATION FAULT HERE
char buffer[BUFFERSIZE];
int i;
i = read(0, buffer, BUFFERSIZE);
它们都在 main 的第一行崩溃(SEGFAULT)。但是,如果我将缓冲区从 main 移到全局范围(因此,在堆中分配而不是在堆栈中),这可以正常工作:
char buffer[BUFFERSIZE]; //NOW GLOBAL AND WORKING FINE
main()
{
int j = BUFFERSIZE;
int i;
i = read(0, buffer, BUFFERSIZE);
我使用 Ubuntu Precise 12.04 64 位和英特尔 i5 M 480 第一代。
#uname -a
Linux hostname 3.2.0-34-generic #53-Ubuntu SMP Thu Nov 15 10:48:16 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
我不知道堆栈的操作系统限制。有没有办法在堆栈中分配大数据,即使这不是一个好习惯?