6

You may think that this is a coincidence that the topic of my question is similar to the name of the forum but I actually got here by googling the term "stack overflow".

I use the OPNET network simulator in which I program using C. I think I am having a problem with big array sizes. It seems that I am hitting some sort of memory allocation limitation. It may have to do with OPNET, Windows, my laptop memory or most likely C language. The problem is caused when I try to use nested arrays with a total number of elements coming to several thousand integers. I think I am exceeding an overall memory allocation limit and I am wondering if there is a way to increase this cap. Here's the exact problem description:

I basically have a routing table. Let's call it routing_tbl[n], meaning I am supporting 30 nodes (routers). Now, for each node in this table, I keep info. about many (hundreds) available paths, in an array called paths[p]. Again, for each path in this array, I keep the list of nodes that belong to it in an array called hops[h]. So, I am using at least nph integers worth of memory but this table contains other information as well. In the same function, I am also using another nested array that consumes almost 40,000 integers as well. As soon as I run my simulation, it quits complaining about stack overflow. It works when I reduce the total size of the routing table. What do you think causes the problem and how can it be solved? Much appreciated Ali

4

6 回答 6

10

It may help if you post some code. Edit the question to include the problem function and the error.

Meanwhile, here's a very generic answer:

The two principal causes of a stack overflow are 1) a recursive function, or 2) the allocation of a large number of local variables.

Recursion

if your function calls itself, like this:

int recurse(int number) {

    return (recurse(number));
}

Since local variables and function arguments are stored on the stack, then it will in fill the stack and cause a stack overflow.

Large local variables

If you try to allocate a large array of local variables then you can overflow the stack in one easy go. A function like this may cause the issue:

void hugeStack (void) {

    unsigned long long reallyBig[100000000][1000000000];

    ...
}

There is quite a detailed answer to this similar question.

于 2008-09-19T23:08:42.893 回答
3

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

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

于 2008-09-19T23:27:53.457 回答
1

Stack overflows can happen in C when the number of embedded recursive calls is too high. Perhaps you are calling a function from itself too many times?

This error may also be due to allocating too much memory in static declarations. You can switch to dynamic allocations through malloc() to fix this type of problem.

Is there a reason why you cannot use the debugger on this program?

于 2008-09-19T23:14:06.437 回答
1

这取决于您在哪里声明了变量。

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

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

于 2008-09-20T00:38:48.183 回答
1

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

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

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

您可能能够找到一些 OS API 函数来强制堆栈分配,或编译器编译指示/标志。我不确定如何以便携方式完成此操作,当然使用 malloc() 和 free() 除外!

于 2008-10-29T20:19:08.990 回答
0

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

于 2008-09-20T13:38:40.727 回答