2

I'm running into a segfault when allocating a dynamic array of large size.

As a specific example, the below code causes a segfault.

int max = 1399469912;
int *arr = (int*) malloc((max+1) * sizeof(int));
arr[0] = 1;

However, if I replace max with something smaller like 5, then I get no segfault.

Why does this happen? Or, is there another solution to achieve the same effect? I need a dynamically allocated array of significant size.

Thanks

4
  • 4
    First of all, should you really cast the result of malloc? Secondly, what if the malloc call fails and return a null pointer? You need to check for that. Commented Jun 8, 2017 at 14:21
  • 3
    A is for Ambition. A is also for Allocation. Trying to allocate 5.6 gigabytes is a rather Ambitious Allocation. Commented Jun 8, 2017 at 14:23
  • 2
    If the arithmetic is done using 64-bit numbers, you're asking for about 5 GiB of memory. Does you system allow you to allocate that much? You must check the return value from malloc() before using it. That isn't always enough (Linux and OOM — Out of Memory — Killer), but it is necessary. Commented Jun 8, 2017 at 14:25
  • I have a hunch the OP is trying to do this on a 32 bit OS. Commented Jun 8, 2017 at 14:26

3 Answers 3

6

Reed documentation of malloc (or malloc(3) from Linux man page)

It can fail, and then returns NULL; and your code should handle that case:

int *arr = malloc((max+1) * sizeof(int));
if (!arr) { perror("malloc arr"); exit(EXIT_FAILURE); };

You could handle the failure in some other ways, but errno is giving the reason. In practice, recovering a malloc or calloc failure is quite tricky. In most cases, exiting abruptly like above is the simplest thing to do. In some cases (think of a server program which should run continuously) you can do otherwise (but that is difficult).

Read also about memory overcommitment (a whole system configurable thing or feature, that I personally dislike and disable, because it might make malloc apparently succeed when memory resources are exhausted; on Linux read about Out-of-memory killer)

See also this (a silly implementation of malloc)

BTW, you need to be sure that (max+1) * sizeof(int) is not overflowing, and you'll better define size_t max = 1399469912; (not int).

Notice that you are requesting (on systems having sizeof(int)==4 like my Linux/x86-64 desktop) more than five gigabytes. This is a significant amount of virtual address space.

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

2 Comments

How can I determine the cause of failure?
+1 for the size_tr suggestion even though in case where the size is known at compile time every good compiler will warn you in case of any overflow =)
3

You have to check whether malloc return a valid pointer or fails to allocate the memory. In that case, it returns a null. pointer.

int max = 1399469912;
int *arr = (int*) malloc((max+1) * sizeof(int));
if( arr == NULL )
{
     /* Malloc failed, deal with it */
}else{
 //fine here
 arr[0] = 1;
}

Quoting the man page

If successful, calloc(), malloc(), realloc(), reallocf(), and valloc() functions return a pointer to allocated memory. If there is an error, they return a NULL pointer and set errno to ENOMEM.

Comments

2

malloc() returns NULL if it wasn't able to allocate the requested memory. You should check the value returned by malloc() against NULL.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.