【问题标题】:Segmentation Fault in C [duplicate]C中的分段错误[重复]
【发布时间】:2016-03-30 04:48:34
【问题描述】:
#include <stdio.h>

int main()
{
    int n[100000];
    int t,q;
    int i,j;
    char s[3][100000];
    char qstr[3][200][100000];
    printf("Success\n");
}

在上面的代码中,qstr 的大小约为 57.22 MiB。当超过 1 GiB 的可用内存仍然可用时,为什么会出现分段错误? 如果我将qstr 的声明更改为qstr[3][200][10000],则程序执行没有问题,并且实际打印“成功”,然后退出。在这种情况下,“qstr”仅占用大约 5.7 MiB。

我有两个问题:

  1. 我怎么知道限制?

  2. 鉴于我有更多可用内存,我该如何利用它?

【问题讨论】:

  • 提示在网站上 :-)
  • 您不能在堆栈上分配所有内容。线程堆栈通常限制在 1-2MB。您需要在堆上分配大对象。

标签: c


【解决方案1】:

答案是堆栈大小。内存有两种:堆和栈。

数组在堆栈中分配。您现在可以使用ulimit -a 命令进行限制。在我的系统上,我得到stack size (kbytes, -s) 8192,所以最多8Mb。你可能也有。

如果要在堆中分配,则需要使用malloc、指针等。

例如

char* qstr = malloc(3 * 200 * 100000);

【讨论】:

  • static char qstr[3][200][100000]; 也可以,但这对多线程进程有影响。
  • 其实自动数组是在栈上分配的。全局数组不是。此外,还可以使用 malloc() 或 calloc() 在堆上分配一个新数组。
  • C 没有指定堆栈/堆,但有 3 种编码范例:1)将事物分为 2 组:堆和堆栈:2)没有。 ;-)
  • @chux haha​​ :) 我承认我的解释不准确,但我相信它回答了这个问题,根据我对 que 作者的经历的猜测。
  • @AndrewHenle 我检查了static 工作,但为什么呢?我的意思是static 局部变量存储在哪里,为什么这不是多线程安全的?另外,全局变量存储在哪里?
【解决方案2】:

如果函数不会被递归调用,则将大型数组设为静态是避免堆栈溢出的一种简单方法。

#include <stdio.h>

int main() {
    static int n[100000];
    int t,q;
    int i,j;
    static char s[3][100000];
    static char qstr[3][200][100000];
    printf("Success\n");
}

如果要使用malloc(),可以这样写:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *n = malloc(sizeof(int[100000]));
    int t,q;
    int i,j;
    char (*s)[100000] = malloc(sizeof(char[3][100000]));
    char (*qstr)[200][100000] = malloc(sizeof(char[3][200][100000]));
    printf("Success\n");
    free(n);
    free(s);
    free(qstr);
}

【讨论】:

  • 如果函数被递归调用怎么办?
  • static 变量与所有调用共享,并且在调用中修改变量(可能是递归中更深层次的调用)确实在以前的变量中接受值。因此,某些使用局部变量的算法可能不起作用!
猜你喜欢
  • 2012-05-26
  • 1970-01-01
  • 2015-05-09
  • 2021-09-26
  • 2016-12-13
  • 2018-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多