Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 什么导致堆栈溢出?_C_Memory_Malloc_Stack Overflow - Fatal编程技术网

C 什么导致堆栈溢出?

C 什么导致堆栈溢出?,c,memory,malloc,stack-overflow,C,Memory,Malloc,Stack Overflow,你可能会认为这是一个巧合,我的问题的主题与论坛的名称相似,但实际上我是通过谷歌搜索“堆栈溢出”一词来到这里的 我使用OPNET网络模拟器,在其中我使用C编程。我认为我有一个大数组大小的问题。似乎我遇到了某种内存分配限制。这可能与OPNET、Windows、我的笔记本电脑内存或最可能的C语言有关。当我尝试使用嵌套数组时,当元素总数达到几千个整数时,就会出现这个问题。我想我已经超过了总的内存分配限制,我想知道是否有办法增加这个上限。 以下是确切的问题描述: 我基本上有一个路由表。我们称之为路由(ro

你可能会认为这是一个巧合,我的问题的主题与论坛的名称相似,但实际上我是通过谷歌搜索“堆栈溢出”一词来到这里的

我使用OPNET网络模拟器,在其中我使用C编程。我认为我有一个大数组大小的问题。似乎我遇到了某种内存分配限制。这可能与OPNET、Windows、我的笔记本电脑内存或最可能的C语言有关。当我尝试使用嵌套数组时,当元素总数达到几千个整数时,就会出现这个问题。我想我已经超过了总的内存分配限制,我想知道是否有办法增加这个上限。 以下是确切的问题描述:

我基本上有一个路由表。我们称之为路由(routing)_tbl[n],这意味着我支持30个节点(路由器)。现在,对于这个表中的每个节点,我保留信息。在称为路径[p]的数组中,大约有许多(数百)条可用路径。同样,对于这个数组中的每个路径,我将属于它的节点列表保存在一个名为hops[h]的数组中。所以,我使用了至少相当于nph整数的内存,但这个表也包含其他信息。在同一个函数中,我还使用了另一个嵌套数组,它也消耗了近40000个整数。 我一运行模拟,它就会停止抱怨堆栈溢出。当我减小路由表的总大小时,它就起作用了。 你认为问题的原因是什么?如何解决? 非常感谢
阿里

如果您发布一些代码,可能会有所帮助。编辑问题以包括问题函数和错误

同时,这里有一个非常笼统的答案:

堆栈溢出的两个主要原因是1)递归函数,或2)大量局部变量的分配

递归

如果函数调用自身,如下所示:

int recurse(int number) {

    return (recurse(number));
}
由于局部变量和函数参数存储在堆栈上,因此它将填充堆栈并导致堆栈溢出

大型局部变量

如果您试图分配一个大的局部变量数组,那么很容易就可以使堆栈溢出。这样的函数可能会导致以下问题:

void hugeStack (void) {

    unsigned long long reallyBig[100000000][1000000000];

    ...
}

对此有一个非常详细的答案。

当嵌入式递归调用的数量太多时,C中可能会发生堆栈溢出。也许您从函数本身调用函数的次数太多了

此错误也可能是由于在静态声明中分配了太多内存。您可以通过malloc()切换到动态分配来解决此类问题


您不能在此程序上使用调试器的原因是什么

不知何故,您使用了大量堆栈。可能的原因包括在堆栈上创建路由表,在堆栈上传递路由表,或者生成大量调用(例如通过递归处理整个过程)


在前两种情况下,您应该在堆上创建它,并传递指向它的指针。在第三种情况下,您需要以迭代形式重写算法。

这取决于您声明变量的位置。

局部变量(即堆栈上声明的一个变量受最大帧大小的限制)这是您正在使用的编译器的限制(通常可以使用编译器标志进行调整)


动态分配的对象(即堆上的对象)受可用内存量的限制。这是操作系统的一个属性(如果你有一个智能操作系统,从技术上讲,物理内存可能会更大)。

除非你做了一些特别令人震惊的事情,比如失控的递归或宇宙内存泄漏,否则你不太可能在无线程编译的C中遇到堆栈溢出。然而,您的模拟器可能有一个线程包,它将施加堆栈大小限制。当您启动一个新线程时,它将为该线程的堆栈分配一块内存。很可能,您可以在某个地方设置一个参数来确定默认堆栈大小,或者有一种方法可以动态增长堆栈。例如,pthreads有一个函数pthread_attr_setstacksize(),您可以在启动新线程之前调用该函数来设置其大小。您的模拟器可能正在使用pthreads,也可能未使用pthreads。请参阅您的模拟器参考文档。

许多操作系统会在您使用更多的堆栈时动态扩展堆栈。当您开始写入刚超出堆栈的内存地址时,操作系统会假定您的堆栈刚刚增长了一点,并为其分配一个额外的页面(x86上通常为4096Kib,精确到1024整数)

问题是,在x86(和其他一些体系结构)上,堆栈向下增长,而C阵列向上增长。这意味着如果您访问一个大数组的开头,您将访问距离堆栈边缘一页以上的内存

如果从数组的末尾开始将数组初始化为0(没错,创建一个for循环来完成此操作),则错误可能会消失。如果他们这样做,这确实是问题所在


您可能会找到一些OSAPI函数来强制堆栈分配,或者编译器pragmas/flags。除了使用malloc()和free()

你能更明确地解释这个问题,而不是你目前的解决方案吗?我想这会鼓励更多的人阅读和回答你的问题。我知道,挑剔,但深度不是“高”,而是“深”。抱歉。从技术上讲,递归函数将被优化为一个简单的无限循环,但我们不要对示例过于悬而未决:)根据描述,这听起来像是在堆栈上推送太多数据而不是递归的问题。我打赌把变量放在堆上(使用malloc)会解决这个问题。是的,这是我一开始得到的答案,但后来我想他可能正在用一些函数遍历他的网络。我想我只需要添加一个基本的参考答案和任何其他对此有疑问的人