-1
// C Program to find average of numbers given by user
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
    double sum = 0;
    int ii = 0,c;
    char buf[256], *token;
    printf("Enter the numbers to average on a single line, separated by space and press enter when done\n");
    fgets(buf, 255, stdin);
    token = strtok(buf, " ");
    while (token != NULL)
    {
        sum += atof(token);
        ii++;
        token = strtok(NULL, " ");  //Get next number
    }
    printf("Average is %lf", sum / (double)ii);
}

第 8 行:

char buf[256], *token;

当我将数组限制更改为任何 8 位或更多位数时,例如 11111111、68297907(等等...),程序就会被编译,但在输出时会显示Segmention Error

如何增加数组限制?我正在使用基于 UNIX 的系统。

4

5 回答 5

4
char buf[11111111];

这超过 11 兆字节。它在堆栈上分配。堆栈的大小是有限的,通常是 8 或 10 兆字节。您遇到堆栈溢出,如果超出该限制,通常会导致段错误

你可以:

  • 如果您的系统支持,请增加堆栈限制。您没有告诉我们您使用的是哪种系统。这通常是通过外壳完成的。对于 bash,运行例如

    ulimit -s 12000
    

    将最大堆栈大小设置为 12000 千字节(120 兆字节)。管理员可能设置了一个限制,阻止您使用这么多的堆栈空间。您必须在运行上述ulimit命令的同一 shell 中运行程序。

  • 动态分配内存:

    char *buf = malloc(11111111);
    
  • 在堆栈之外的其他地方分配空间:

    static char buf[11111111];
    

我会质疑是否需要允许某人在一行上输入 11 兆字节的数据。

于 2013-10-09T11:24:34.630 回答
2

您可能需要增加允许的堆栈大小:

http://www.ss64.com/bash/ulimit.html

或者您可以尝试动态分配内存,而不是使用 malloc 在堆栈上分配内存:

char *buf = malloc(A_BIG_NUM);
于 2013-10-09T11:12:01.233 回答
2

*nix 上的堆栈大小通常默认设置为 8MB。包含 11111111 个元素的 char 数组约为 11MB,比堆栈大得多结果会导致堆栈溢出

您可以使用 增加堆栈大小ulimit,但增加太多也不好。对于大数组,您应该改用堆分配

于 2013-10-09T11:15:46.307 回答
1

讲道理。数组 buf 用于读取文本形式的数字。没有人需要输入 10 亿位数字(尝试缓冲区溢出攻击的除外),没有已知的 C 实现支持 10 亿位浮点数或双精度数的指数或尾数。

过多和不必要的数组大小超出了堆栈大小的实现限制,并在您的情况下导致分段违规。

于 2013-10-09T11:21:27.290 回答
0

一切都写在上面了。由于克服了允许的堆栈大小,程序在启动时收到信号 SIGSEGV。
下面是另一种确定实际堆栈大小(软限制和硬限制)的方法:

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
void main() {
  struct rlimit rl;
  int ss = getrlimit(RLIMIT_STACK, &rl);
  printf("soft = %lu, hard = %lu\n", rl.rlim_cur, rl.rlim_max);
}
于 2013-10-09T11:58:24.447 回答