how to fix stack overflow error?

-2

so, i was making this program that let people know the number of contiguous subarray which sum is equal to a certain value.

i have written the code , but when i try to run this code in vcexpress 2010, it says these error

Unhandled exception at 0x010018e7 in test 9.exe: 0xC00000FD: Stack overflow.

i have tried to search for the solution in this website and other webisites, but i can't seem to find any solution which could help me fix the error in this code(they are using recursion while i'm not).

i would be really grateful if you would kindly explain what cause this error in my code, and how to fix this error. any help would be appreciated. Thank you.

here is my code :

#include <stdio.h>

int main ()
{
    int n,k,a=0,t=0;
    unsigned long int i[1000000];
    int v1,v2=0,v3;

    scanf("%d %d",&n,&k);

    for(v3=0;v3<n;v3++)
    {
    scanf("%d",&i[v3]);
    }

    do
    {
        for(v1=v2;v1<n;v1++)
        {
            t=i[v1]+t;
            if(t==k)
            {
                a++;
                break;
            }
        }
        t=0;
        v2++;
    }while(v2!=n);

    printf("%lu",a);


    return 0;

}
c
stack-overflow

3 Answers

3

Either move

     unsigned long int i[1000000];

outside of main, thus making it a global variable (not an automatic one), or better yet, use some C dynamic heap allocation:

 // inside main
 unsigned long int *i = calloc(1000000, sizeof(unsigned long int));
 if (!i) { perror("calloc"); exit(EXIT_FAILURE); };

BTW, for such a pointer, I would use (for readability reasons) some other name than i. And near the end of main you'll better free(i); to avoid memory leaks.

Also, you could move these 2 lines after the read of n and use calloc(n, sizeof(unsigned long int)) instead of calloc(1000000, sizeof(unsigned long int)) ; then you can handle arrays bigger than a million elements if your computer and system provides enough resources for that.

Your initial code is declaring an automatic variable which goes into the call frame of main on your call stack (which has a limited size, typically a megabyte or a few of them). On some operating systems there is a way to increase the size of that call stack (in an OS-specific way). BTW each thread has its own call stack.

As a rule of thumb, your C functions (including main) should avoid having call frames bigger than a few kilobytes. With the GCC compiler, you could invoke it with gcc -Wall -Wextra -Wframe-larger-than=1024 -g to get useful warnings and debug information.

Read the virtual address space wikipage. It has a nice picture worth many words. Later, find the way to query, on your operating system, the virtual address space of your process (on Linux, use proc(5) like cat /proc/$$/maps etc...). In practice, your virtual address space is likely to contain many segments (perhaps a dozen, sometimes thousands). Often, the dynamic linker or some other part of your program (or of your C standard library) uses memory-mapped files. The standard C heap (managed by malloc etc) may be organized in several segments.

If you want to understand more about virtual address space, take time to read a good book, like: Operating systems, three easy pieces (freely downloadable).

If you want to query the organization of the virtual address space in some process, you need to find an operating-system specific way to do that (on Linux, for a process of pid 1234, use /proc/1234/maps or /proc/self/maps from inside the process).

answered on Stack Overflow Nov 12, 2017 by Basile Starynkevitch • edited Nov 12, 2017 by Basile Starynkevitch
1

Memory is laid out much more differently than simply 4 segments(which was done long ago). The answer to the question can be generalized this way - the global or dynamically allocated memory space is handled differently than that of local variables by the system, where as the memory for local variable is limited in size, memory for dynamic allocation or global variables doesn't put a lower constraint like this.

In modern system the concept of virtual address space is there. The process from your program gets a chunk of it. That portion of memory is now responsible for holding the required memory.

Now for dynamic allocation and so on, the process can request more memory and depending on the other processes and so on, new memory request is serviced. For dynamic or global array there is no limit process wise (of course system wise there is- it cant haverequest all memory). That's why dynamic allocation or using global variable won't cause the process to run out of it's allocated memory unlike the automatic lifetime memory that it originally had for local variables.

answered on Stack Overflow Nov 12, 2017 by user2736738 • edited Nov 12, 2017 by user2736738
0

Basically you can check your stack size for example in Linux : ulimit -s (Kbytes) and then decide how you manipulate your code regarding that. As a concept I would never allocate big piece of memory on the stack because unless you know exactly the depth of your function call and the stack use, it's hard to control the precised allocated memory on stack during run time

answered on Stack Overflow Nov 12, 2017 by Elad Hazan

User contributions licensed under CC BY-SA 3.0