0
#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");
}

In the above code the size of qstr is about 57.22 MiB. Why is there a Segmentation fault when more than 1 GiB of free memory is still available? If I change the declaration of qstr as qstr[3][200][10000] the program has no trouble executing and "Success" is actually printed, after which it exits. In this case 'qstr' is only occupying about 5.7 MiB.

I have 2 questions:

  1. How do I know the limit?

  2. Given that I've way more free memory, how do I exploit it?

Mayank Verma
  • 633
  • 6
  • 19

2 Answers2

6

THe answer is the stack size. There are two memories: the heap and the stack.

Arrays are allocated in the stack. You can now the limit with the ulimit -a command. On my system, I get stack size (kbytes, -s) 8192, so 8Mb at most. You probably have the same.

If you want to allocate in the heap, you will need to play with malloc, pointers etc.

For instance

char* qstr = malloc(3 * 200 * 100000);
Tristram Gräbener
  • 9,601
  • 3
  • 34
  • 50
  • 2
    `static char qstr[3][200][100000];` would also work, but that has implications for multithreaded processes. – Andrew Henle Dec 23 '15 at 17:42
  • Actually, automatic arrays are allocated on the stack. Global arrays are not. Additionally, it is possible to allocate a new array on the heap with malloc() or calloc(). – ash Dec 23 '15 at 18:10
  • 1
    C does not specify stack/heap, yet there are 3 types of coding paradigms: 1) Ones that divide things into 2 groups: heap & stack: 2) Ones that don't. ;-) – chux - Reinstate Monica Dec 23 '15 at 23:14
  • 1
    @chux haha :) I admit that my explanations isn’t accurate, but I believe that it answers the question, from what I guess about the experience of que author. – Tristram Gräbener Dec 24 '15 at 10:18
  • @AndrewHenle I checked `static` works, but why? I mean where are `static` local variables stored and why is this not multithread safe? Also, where are global variables stored? – Mayank Verma Dec 26 '15 at 07:08
  • Is there a standard library function to determine stack size? – Mayank Verma Dec 26 '15 at 07:14
  • @MayankVerma Adding the `static` keyword to a local variable definition causes the variable to have `static` *duration*, which means it continues to exist both before and after the function call - and retains its value between calls. Without the `static` the variable is an *automatic* variable that exists only as long as the function is running - a "normal", local stack variable. If a function is called by multiple threads at the same time, each separate thread gets its own copy of *automatic* or "normal" stack variables. – Andrew Henle Dec 27 '15 at 16:08
  • (cont) **But** if you add the `static` keyword, there's only *one* copy of the variable - and it's shared by all threads. Effectively, instead of getting a copy of the variable on the stack for each and every call to the function, you get **one** copy of the variable located somewhere in memory. Since it's not on the stack, stack size limits don't apply. – Andrew Henle Dec 27 '15 at 16:09
1

Making large arrays static is a easy way to avoid stack overflow if the function won't be called recursively.

#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");
}

If you want to use malloc(), It can be written like this:

#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);
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • What if the function is called recursively? – Mayank Verma Dec 26 '15 at 07:11
  • `static` variables are shared with all calling and modifying ones in a calling (maybe deeper call in recursion) do accect value in previous ones. Therefore, some algorithm which use local variables may not work! – MikeCAT Dec 26 '15 at 07:22