分段错误:当缓冲区大于 4M 时,Ubuntu 中 C 程序中的堆栈分配 [英] Segmentation fault: Stack allocation in a C program in Ubuntu when bufffer>4M

查看:10
本文介绍了分段错误:当缓冲区大于 4M 时,Ubuntu 中 C 程序中的堆栈分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个完成大学任务的小程序:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆