分段错误:当缓冲区大于 4M 时,Ubuntu 中 C 程序中的堆栈分配 [英] Segmentation fault: Stack allocation in a C program in Ubuntu when bufffer>4M
问题描述
这是一个完成大学任务的小程序:
Here's a small program to a college's task:
#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 函数.
There is a alternative using the stdio.h fread and fwrite functions instead.
嗯.我用 25 个不同的缓冲区大小值编译了这两个版本的程序:1、2、4、...、2^i,i=0..30
Well. I compiled this both versions of program with 25 different values of Buffer Size: 1, 2, 4, ..., 2^i with i=0..30
这是我如何编译它的示例:gcc -DBUFERSIZE=8388608 prog_sys.c -o bin/psys.8M
This is a example of how I compile it: gcc -DBUFFERSIZE=8388608 prog_sys.c -o bin/psys.8M
问题:在我的机器上(Ubuntu Precise 64,最后有更多细节)所有版本的程序都可以正常工作:./psys.1M <数据
The question: In my machine (Ubuntu Precise 64, more details in the end) all versions of the program works fine: ./psys.1M < data
(数据是一个带有 3 行 ascii 文本的小文件.)
(data is a small file with 3 line ascii text.)
问题是:当缓冲区大小为 8MB 或更大时.两个版本(使用系统调用或 clib 函数)都会因这些缓冲区大小而崩溃(分段错误).
The problem is: When the buffer size is 8MB or greater. Both versions (using system call or clib functions) crashes with these buffer sizes (Segmentation Fault).
我测试了很多东西.代码的第一个版本是这样的:(...)主要的(){字符缓冲区[BUFFERSIZE];诠释我;
I tested many things. The first version of the code was like this: (...) main() { char buffer[BUFFERSIZE]; int i;
i = read(0, buffer, BUFFERSIZE);
(...)
当我调用读取函数时,这会崩溃.但是对于这些版本:
This crashs when I call the read function. But with these versions:
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 移到全局范围(因此,在堆中分配而不是在堆栈中),这可以正常工作:
Both them crashs (SEGFAULT) in the first line of main. However, if I move the buffer out of main to the global scope (thus, allocation in the heap instead the stack), this works fine:
char buffer[BUFFERSIZE]; //NOW GLOBAL AND WORKING FINE
main()
{
int j = BUFFERSIZE;
int i;
i = read(0, buffer, BUFFERSIZE);
我使用的是 Ubuntu Precise 12.04 64 位和第一代 Intel i5 M 480.
I use a Ubuntu Precise 12.04 64bits and Intel i5 M 480 1st generation.
#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
我不知道堆栈的操作系统限制.有没有办法在堆栈中分配大数据,即使这不是一个好习惯?
I don't know the OS limitations about the stack. Is there some way to allocate big data in stack, even if this is not a good pratice?
推荐答案
在 Linux 中堆栈大小经常受到限制.命令 ulimit -s
将给出当前值,以千字节为单位.您可以(通常)更改文件 /etc/security/limits.conf
中的默认值.您还可以根据权限,通过代码在每个进程的基础上更改它:
The stack size is quite often limited in Linux. The command ulimit -s
will give the current value, in Kbytes. You can change the default in (usually) the file /etc/security/limits.conf
. You can also, depending on privileges, change it on a per-process basis via the code:
#include <sys/resource.h>
// ...
struct rlimit x;
if (getrlimit(RLIMIT_STACK, &x) < 0)
perror("getrlimit");
x.rlim_cur = RLIM_INFINITY;
if (setrlimit(RLIMIT_STACK, &x) < 0)
perror("setrlimit");
这篇关于分段错误:当缓冲区大于 4M 时,Ubuntu 中 C 程序中的堆栈分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!