3

Here is the scenario: I am declaring an array and NOT USING IT ANY WHERE IN THE PROGRAM yet. If I declare it to be of length 100 or less, it works fine. For greater length, it gives segmentation fault. I can't understand this behavior.

ATL_RAM_BUFFER_L3 an_unknown_array[128];

Where ATL_RAM_BUFFER_L3 is a structure of almost 72KB.

8
  • Declare it globally or dynamic-allocate it. you're talking about over 9MB of static allocation, which is likely way over your stack-size. Commented Jan 17, 2013 at 7:14
  • May be there is not that much room in memory to fit 128*72 KB Commented Jan 17, 2013 at 7:14
  • it still gets allocated on the stack and any subsequent allocations will therefore be out of bounds. Commented Jan 17, 2013 at 7:14
  • On side note, What kind of structure is this which in 72KB in size.? Commented Jan 17, 2013 at 7:15
  • 1
    @CashifIlyas The global declaration places the variable in your in your DATA segment of your load image and out of the limited space your executing thread has access to on the local call stack. Commented Jan 17, 2013 at 7:24

2 Answers 2

4

You're blowing out your stack which is typically a limited resource, in your case not enough to hold the nine or so megabytes your array takes up.

There are a couple of possible solutions. If you only need one copy, you can declare it outside the function (or as a static within the function) - this will generally keep it off the stack and put it into an area with less limited storage.

Alternatively, you can allocate it dynamically, and ensure you manage it properly.

You may also be able to configure a larger stack size depending on the environment.


By way of example, the following bash script will work out how much data you can allocate on the stack in your (default) environment:

((sz = 0)) ((delta = 1000000)) while [[ ${delta} -gt 0 ]]; do while true; do sleep 1 ((sz += delta)) printf "Trying ${sz} ... " rm -f qq.c echo "#include <stdio.h>" >>qq.c echo "int main (void) {" >>qq.c echo " char buff[${sz}];" >>qq.c echo " puts (\"hello\");" >>qq.c echo " return 0;" >>qq.c echo "}" >>qq.c gcc -o qq qq.c trap 'echo "segfault!"' CHLD rm -f flagfile ( bash -c './qq >flagfile 2>/dev/null' ) >/dev/null 2>&1 if [[ "$(cat flagfile)" == "hello" ]]; then echo "okay" else echo "crashed" ((sz -= delta)) break fi done ((delta = delta / 10)) done 

It works by constructing a C program of the form:

#include <stdio.h> int main (void) { char buff[XYZZY]; puts ("hello"); return 0; } 

where XYZZY is gradually changed to see where the program first crashes from lack of stack space. The output in my environment (CygWin) goes something like this:

Trying 1000000 ... okay Trying 2000000 ... okay Trying 3000000 ... crashed Trying 2100000 ... crashed Trying 2010000 ... okay Trying 2020000 ... okay Trying 2030000 ... okay Trying 2040000 ... okay Trying 2050000 ... okay Trying 2060000 ... okay Trying 2070000 ... okay Trying 2080000 ... crashed Trying 2071000 ... crashed Trying 2070100 ... crashed Trying 2070010 ... okay Trying 2070020 ... okay Trying 2070030 ... okay Trying 2070040 ... okay Trying 2070050 ... okay Trying 2070060 ... okay Trying 2070070 ... crashed Trying 2070061 ... okay Trying 2070062 ... okay Trying 2070063 ... okay Trying 2070064 ... okay Trying 2070065 ... crashed 

meaning that two megabytes is about where it maxes out.

Sign up to request clarification or add additional context in comments.

2 Comments

@CashifIlyas because static buffers won't be on the stack
@Cashif, because that gives it static storage duration, which usually puts it into an area of greater capacity than the stack.
0

The memory for local variables is assigned/freed on the run time. They get created on stack and every thread/process has a limited stack. The size of the stack largely depends on the compiler and operating system. It varies from one system to another. In Unix/Linux type of systems, programs will through segmentation fault when stack overflow occurs. Look at this document for more details on this subject.

On the other hand, the memory for global variables get allocated when the program is loaded in memory. They are assigned memory in BSS section if they were not initialized or Data section if they were initialized to some value. Normally these sections have a lot more room than the stack of a process. So it is generally advisable to declare large variables/objects, like yours, globally to avoid this problem.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.