段故障:在Ubuntu中C程序堆栈分配时bufffer> 4M [英] Segmentation fault: Stack allocation in a C program in Ubuntu when bufffer>4M

查看:162
本文介绍了段故障:在Ubuntu中C程序堆栈分配时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 -DBUFFERSIZE = 8388608 prog_sys.c -o斌/ 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&LT;数据

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).

我测试了很多东西。在code的第一个版本是这样的:
    (......)
    主要()
    {
        字符缓冲区[BUFFERSIZE]
        INT I;

I tested many things. The first version of the code was like this: (...) main() { char buffer[BUFFERSIZE]; int i;

    i = read(0, buffer, BUFFERSIZE);
(...)

这crashs当我打电话的读取功能。但随着这些版本:

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);

他们两个crashs(段错误)在主要的第一行。但是,如果我移动缓冲出主让全球范围内(因此,在堆而不是堆栈分配),这工作得很好:

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的$ P $ 12.04 pcise 64位和英特尔酷睿i5 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 会给当前值,以KB为单位。您可以更改(通常)文件 /etc/security/limits.conf文件默认值。您也可以根据权限,改就通过code每个进程的基础上:

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");

这篇关于段故障:在Ubuntu中C程序堆栈分配时bufffer&GT; 4M的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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