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)
.
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.
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.
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.
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.
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 malloc
ated 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With