malloc works like calloc

214 Views Asked by At

When malloc run, it generate memory block, which doesn't set any value and it contains garbage values. When calloc run, some event happened like a malloc function but there is one difference. When calloc generate new block, it sets 0(Zero) in the block.

#include <stdio.h>
#include <stdlib.h>
int main(void){
    int i,j;
    int* array1 = (int*)malloc(sizeof(int)*5);
    int* array2 = (int*)calloc(sizeof(int),5);
    for(i = 0; i < 5; i++){
        printf("%p: %d\n",&array1[i],array1[i]);
    }
    printf("===================\n");
    for(j = 0; j < 5; j++){
        printf("%p: %d\n",&array2[j],array2[j]);
    }
    return 0;
}

According to this information, first five values must contain garbage values (Actually it should look like random data), second five values must be zero. However when this code was run in Windows, there is no problem, but when this code was run in Linux, this condition doesn't procure. I thought it depend ASLR or DEP protection, and I shut down ASLR and I used old Linux system for DEP protection, but result is same. Finally, I thought that it may depend C Standard and I changed C Standard when Code was compiled but result is not different. I'm asking that what is the reason.

2

There are 2 best solutions below

0
On BEST ANSWER

The behavior of malloc is, that it returns uninitialized memory. Reading from uninitialized memory is undefined behaviour, which means, anything may happen; and a sufficiently smart compiler that detects, that you're reading from uninitialized memory might even optimize out the read and replace it with a constant value, or even terminate your program.

That being said, that you're reading zeros instead of leftover values of whatever happened to reside in that part of the memory is due to security concerns. A few years back it would actually have behaved that way. But then people realized, that this might leak keys or other secrets and hence the behavior of Linux' (and *BSD's) kernel was changed so that memory pages are zeroed out at the first time they're mapped to a process. For Linux this behavior was introduced in Linux-2.6.33. The mmap syscall (which is what the malloc/calloc allocators use internally to talk to the kernel) gained a new flag:

MAP_UNINITIALIZED (since Linux 2.6.33)

Don't clear anonymous pages. This flag is intended to improve performance on embedded devices. This flag is only honored if the kernel was configured with the CONFIG_MMAP_ALLOW_UNINITIALIZED option. Because of the security implications, that option is normally enabled only on embedded devices (i.e., devices where one has complete control of the contents of user memory).

0
On

malloc doesn't fill data with zeros (as you expected). But it is not guaranteed, that garbage data is not zeros. So it's ok, if you allocate memory and see all fields zeroed sometimes or in some cases. I assume you will see "more random" data in "mallocated" memory if size will be much bigger, or if you will allocate, fill with smth, free, allocate again. But with calloc you'll still see zeroed memory even after such manipulations.