2

I am really new to C, so I am sorry if this is a absolute beginner question, but I am getting a segmentation error when I am building large array, relevant bits of what I am doing is:

unsigned long long ust_limit;
unsigned long long arr_size;

/* ust_limit gets value around here ... */

arr_size = ((ust_limit + 1) / 2) - 1;
unsigned long long numbs[(int)arr_size];

This works for some values of ust_limit, but when it gets above approximately 4.000.000 a segmentation fault occurs. What I want is to detect a possible segfault and fail gracefully. How can I know which values would cause a segmentation fault. And, is this something platform dependant?

yasar
  • 13,158
  • 28
  • 95
  • 160

4 Answers4

6

You are most likely getting a stack overflow, since you are creating a very large array on the stack. To avoid this, allocate the memory dynamically:

unsigned long long *numbs = malloc(arr_size * sizeof(unsigned long long));

Later, when you are finished with the array, free it again:

free(numbs);
sth
  • 222,467
  • 53
  • 283
  • 367
  • Can I use numbs like how would I use an array after doing this? For example, can I access indexes? – yasar Oct 06 '11 at 18:42
  • Yes, you can use it the same way. For example indexing works the same on a pointer to some memory as it works on an array. – sth Oct 06 '11 at 18:47
1

You array stores on stack frame, which has a limit to its size, use malloc instead.

unsigned long long *numbs = malloc(arr_size * sizeof(long long));
// don't forget to free after use
free(numbs)
lostyzd
  • 4,515
  • 3
  • 19
  • 33
1

You're consuming too much stack. The limit is platform dependent.

The exact limit depends on the OS. These limits can be changed to some extent on some operating systems .

For large amounts of memory, you should be using the head with malloc and/or calloc (and free).

Mat
  • 202,337
  • 40
  • 393
  • 406
1

numbs is a Variable Length Array (VLA).

VLAs can be created only in block scope (i.e., inside a function). They're allocated like any other local variable, typically on the stack.

Unfortunately, the language doesn't provide a way of detecting or handling allocation failures for local variables. If you allocate too much memory, your program will crash if you're lucky.

Large objects whose size isn't known at compile time should be allocated via malloc() (which means you need to keep track of the allocation and release them with free()).

Incidentally, there's no need to cast arr_size to int. And both ust_limit and arr_size should be of type size_t (defined in <stddef.h>).

Example:

unsigned long long numbs = malloc(arr_size * sizeof *numbs);
/* And later, when you're done with it */
free(numbs);
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631