【问题标题】:printf command causing a seg fault? [duplicate]printf 命令导致段错误? [复制]
【发布时间】:2013-05-28 21:53:09
【问题描述】:

当我尝试初始化一个大的二维字符数组时,它工作得非常好。但是当我添加一个简单的打印命令时,它给了我一个分段错误。关于为什么会发生这种情况的任何想法?

#include<stdio.h>
int main(void)
{
    printf("!");  
    char f[10000][10000];
}

没有 printf 命令,或者即使 printf 命令什么也不打印,它也能正常工作(即“”)。如果我让它打印任何东西,它会给出错误。

有什么帮助吗?

【问题讨论】:

  • 我认为使用普通的“C”语言实际上会出现编译错误(在非定义语句之后定义 f)。
  • @Nicholaz,OP 的程序在 C99 或更高版本中都很好(C99 已经快 15 年了)。
  • @Carl:好的,明白了……(我还是更老派:-))

标签: c arrays segmentation-fault printf stack-overflow


【解决方案1】:

这可能是因为您超出了堆栈。您对f 的定义占用了 100MB 堆栈空间(10000x10000 字节),并且可能一旦您实际使用堆栈,系统就会发现堆栈和段错误没有那么多空间。调用任何其他函数时,您可能会发现相同的情况。

该大小的分配应通过 malloc() 完成。

   char *f= malloc(10000*10000);

   // access two dimensionally (equivalent of f[5][8])
   char z= f[5*10000 + 8];

【讨论】:

  • 通常静态存储类分配也可以。为什么不直接分配一个二维数组,而不是自己做访问乘法体操呢?
  • +1。或者,char (*f)[10000] = malloc(sizeof(*f) * 10000) 也将避免堆栈溢出,同时仍允许将f 索引为二维数组。将f 设为静态可能会产生没有吸引力的副作用 - 将 100Mb 的可执行文件映射到内存中。
  • @simonc,将 f 设为静态可能对可执行文件大小没有影响 - 它将被零初始化。
  • ... 为了达到极致,您可以将其分配为char (*f)[10000][10000] = malloc(sizeof *f)。请记住,在这种情况下,您必须以 (*f)[i][j] 的身份访问它 :))
  • LOL ...我刚刚想到,这个问题是这个网站的缩影,堆栈溢出:-)
【解决方案2】:

您的 C 实现超出了未指定的限制,特别是具有自动存储持续时间(又名“局部变量”)的对象的总大小。 f[] 的大小为 100.000.000 字节。许多 C 实现将自动变量保留在堆栈上,这通常是有限的资源。在我的 Unix 系统 (FreeBSD) 上,我可以检查这个限制:

$ ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          33554432
-s: stack size (kbytes)             524288
[...]

如果允许更高的功率,请使用ulimit -s number 增加它。

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 2021-11-06
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 2011-11-22
    相关资源
    最近更新 更多