Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do statically allocated arrays in C use all of their memory even when some of their elements are not specified?

Tags:

c

Consider the following code:

int array[1000000];
array[1] = 1;
array[10] = 10;

We've statically allocated memory for this array with size 1000000. But is all of this used?

I mean if we did this instead:

int *array = malloc(sizeof(int) * 1000000);
array[1] = 1;
array[10] = 10;

Then it seems that we actually use all of those 1000000 spaces: since we have allocated them, they can't be used for anything else in memory. But for the statically allocated array, things are uninitialized, so things can still be stored in the remaining 999998 spots that do not have a set value.

Essentially what I'm asking is: will int array[num] use less memory than int array = malloc(sizeof(int) * num).

like image 636
herophant Avatar asked Aug 11 '19 07:08

herophant


People also ask

What is an example of static memory allocation in C?

This is an example of static memory allocation because the size of the array is fixed, i.e., size is 35 as demonstrated by int x [35]. You cannot alter the size of the array at the runtime of the program. That’s all about static memory allocation.

When is the memory allocated in C++?

The memory is allocated during compile time. Dynamic Memory Allocation: Memory allocation done at the time of execution (run time) is known as dynamic memory allocation. Functions calloc () and malloc () support allocating dynamic memory.

What are the advantages and disadvantages of static memory allocation?

Advantages of Static memory allocation 1 Simplicity of usage. 2 Efficient execution time. 3 Need not worry about memory allocation/re-allocation/freeing of memory 4 Variables remain permanently allocated.

What is the difference between stack memory and static memory?

All local variables are stored in stack memory at compile-time and all pointer variables are stored in heap memory at the runtime of a program In static memory allocation, memory allocated is fixed which cannot be changed or altered after allocation.


1 Answers

If you have int array[1000000]; and only use a few of its initial members, then in some circumstances (if array is either static or a local of if it's a global and you're linking statically with link time optimizations) your toolchain can shrink/eliminate the array under the as-if rule. (Note that global and static variables are not in effect uninitialized--the C standard mandates that they be zero-initialed.)

Gcc and clang do it, and clang does it even with mallocated arrays to the point that the entire malloc-free pair can be eliminated:

Example:

#include <stdio.h>
#include <stdlib.h>

//gcc and clang optimize out the array, only using
//the constants 1 and 10
int pr(void)
{
   int array[1000000];
   array[1] = 1;
   array[10] = 10;
   return printf("%d %d", array[1], array[10]);
}
//clang optimizes out the dynamic allocation of array,
//only using the constants 1 and 10
int pr1(void)
{
   int r;
   int *array = malloc(1000000);
   if(!array) return -1;
   array[1] = 1;
   array[10] = 10;
   r = printf("%d %d", array[1], array[10]);

   free(array);
   return r;
}

Example output assembly on x86-64 clang with -O3:

pr:                                     # @pr
        mov     edi, offset .L.str
        mov     esi, 1
        mov     edx, 10
        xor     eax, eax
        jmp     printf                  # TAILCALL
pr1:                                    # @pr1
        mov     edi, offset .L.str
        mov     esi, 1
        mov     edx, 10
        xor     eax, eax
        jmp     printf                  # TAILCALL
.L.str:
        .asciz  "%d %d"

Check it out at https://gcc.godbolt.org/z/UmiA34.

Such optimizations are nonportable and twitchy, however. The simplest things such passing a pointer to an array to a function defined in a different translation unit can turn them off. I would avoid relying on them.

like image 174
PSkocik Avatar answered Oct 21 '22 10:10

PSkocik