Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the Memory locations for two variables which is allocated dynamically are not consecutive? [duplicate]

Tags:

c++

c

linux

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.

like image 248
naveen kumar Avatar asked Jul 28 '17 03:07

naveen kumar


People also ask

Why do we allocate memory dynamically?

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.

What happens when dynamically allocated memory is not freed?

If dynamically allocated memory is not freed, it results in a memory leak and system will run out of memory.

How dynamic memory is allocated?

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.

Where are dynamic variables stored in 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.


1 Answers

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 ints at consecutive addresses, allocate an array.

like image 115