I use two variables in which memory is allocated dynamically, and I print the memory locations, but they are not consecutive. Why?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int));
printf("\n a=%p \t b=%p \n",a,b);
}
The answers I get (in Linux) are
1st time:
a=0x20a0010 b=0x20a0030
2nd time:
a=0x657010 b=0x657030
3rd time:
a=0x139e010 b=0x139e030
Why is the exact difference between the memory locations of a
and b
variables the way it is in the 1st, 2nd and 3rd times?
Is this related to paging memory?
My processor is 64 bit.
Dynamic memory allocation is the process of assigning the memory space during the execution time or the run time. Reasons and Advantage of allocating memory dynamically: When we do not know how much amount of memory would be needed for the program beforehand.
If dynamically allocated memory is not freed, it results in a memory leak and system will run out of memory.
In C, dynamic memory is allocated from the heap using some standard library functions. The two key dynamic memory functions are malloc() and free(). The malloc() function takes a single parameter, which is the size of the requested memory area in bytes. It returns a pointer to the allocated memory.
Dynamically allocated variables live in a piece of memory known as the heap, these are requested by the running program using the keyword "new". A dynamic variable can be a single variable or an array of values, each one is kept track of using a pointer.
The gap between two consecutive allocations is not related to paging. Your allocations are so small that they reside in the data segment. Libc handles these internally - the space outside your sizeof int
bytes generally contains pointers to the previous and the next block of data and the size of allocation - after all free
will just get a pointer and it will need to figure out how much memory it is to deallocate.
Additionally both of these pointers are aligned to 16-byte boundary. C11 7.22.3 says that
The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated).
Thus even though you're using them for int
the C standard requires that the pointer returned be aligned for any data type - which on your implementation is 16 bytes.
If however you allocate an object that is very large, glibc will map entire pages using mmap
instead. Then the alignment (on my 64-bit computer) is exactly 16 bytes from the start of a 4K page:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = malloc(12345678);
int *b = malloc(12345678);
printf("\n a=%p \t b=%p \n",a,b);
}
when run
% ./a.out
a=0x7fb65e7b7010 b=0x7fb65dbf0010
One can see the mmap
calls with strace ./a.out
- there among other system calls there are
mmap(NULL, 12349440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb65e7b7000
mmap(NULL, 12349440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb65dbf0000
As for why the addresses keep changing from one execution to another - this is due to address space layout randomization, or ASLR - a security mechanism which makes it harder for evil crackers to predictably exploit undefined behaviour in your code.
P.S. If you really need to dynamically allocate space for 2 int
s at consecutive addresses, allocate an array.
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