4

I'm starting to learn about dynamic memory allocation in C and so far everywhere I've read the malloc() function does NOT initialize the value of the newly allocated block.

Has this been changed in newer versions of C? C99 and C11?

I'm executing the following using Xcode and all values are being initialized with 0.

double *p = (double *) malloc(5 * sizeof(double));

printf("Address of p0 = %p | Valoe of p0 = %f\n", p, *p);
printf("Address of p1 = %p | Valoe of p1 = %f\n", p+1, *(p+1));
printf("Address of p2 = %p | Valoe of p2 = %f\n", p+2, *(p+2));
printf("Address of p3 = %p | Valoe of p3 = %f\n", p+3, *(p+3));
printf("Address of p4 = %p | Valoe of p4 = %f\n", p+4, *(p+4));

I thought this was true only for the function calloc().

  • 2
    I think it is because the memory you malloced is not used by other non-zero variables before. You can't be sure that it is always so. – lulyon Jul 14 '13 at 11:50
  • 1
    seems to be undefined behavior. Repeat this a few more times and check if you still get 0. – Nithin Bhaskar Jul 14 '13 at 11:52
  • Just use `calloc` if you want a zero-initialized area. – Daniel Kamil Kozar Jul 14 '13 at 12:20
  • 3
    On a multi-user operating system, when the OS gives you a new page of memory, it has to be "clean" so that you don't see anything you're not supposed to see. An easy way to achieve this is to give you a page full of zeros. – Kerrek SB Jul 14 '13 at 12:22
  • You're only doing 1 malloc call. Your OS (not "malloc"), will usually hand out new memory that is zeroed out, so to not leak information from other processes that used that memory previously. I suggest you do a handful of malloc, fill the memory with something, free() it, and malloc() again. There's a bigger chance you get old stuff back, as the same memory is reused. – nos Jul 14 '13 at 12:43

6 Answers6

10

Seems to be implementation defined behavior. On Visual Studio 2012, C compiler, I see no such initializations.

More importantly, read the "catch" of the selected answer in this question:

Why does malloc initialize the values to 0 in gcc?

Says, that the OS might "give" you zeroed values due to security reasons. As it seems, this is an implementation defined behavior.

Piece of advice: its not standard behavior and breaks portability of the code. Make sure you initialize the values and not depend on the data given by the OS .

Community
  • 1
  • 1
Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
4

You got lucky(or unlucky if you trust this). Malloc does not have such thing inside(but it asks to OS to get allocation and I dont know OS behavior). Then there could be some performance decrease when you repeatedly malloc some areas. Those zeroes are from untouched forest.

First malloc, then initialize to random numbers/chars then repeat this many times, then you will start getting non-zero elements just after malloc.

Dont forget to free() between random sized mallocs.

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
  • Hi Huseyin thanks for the great reply. I've done what you suggested. 1 - Allocated memory using malloc for 5 int values. 2 - Randomly initialized the 5 ints using srand() and random() 3 - Printed the values 4 - used free() 5 - Allocated a new memory for 5 int values 6 - printed the values again For my surprise the values printed on step 6 were the old values from step number 3. So you are right... The newly allocated memory this time was not initialized with zeros. Instead it just took the random values from step number 2. – Italo Grossi Jul 14 '13 at 12:08
  • But you may need to sweep whole compiler's work area to be sure to get non-zero :) this may need many mallocs. :) Have fun. – huseyin tugrul buyukisik Jul 14 '13 at 12:10
3

You've assumed that "I get 0" always means "the value 0 was deliberately placed here", which is not the case.

There is no initialisation in your code.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

First, the fact that malloc does not initialize the returned memory block (this has not changed) as per the standard does not mean that it must not do it, but rather that it is not required to do so.

It is very well allowable for malloc to initialize the memory block anyway. It is even conceivable (but unwise) for a debug build to zero-initialize all allocated blocks. A better solution would be to fill them with a recognizable pattern, however.

On top of that, new pages obtained from the operating system are always zeroed. This is done for security reasons, with no exceptions (some embedded systems may be the rare exception, but no "mainstream" system will give you an uninitialized page, ever). Therefore, in some cases, memory may be zero-initialized, but you have no way of knowing whether it was malloc doing it or someone else.

Damon
  • 67,688
  • 20
  • 135
  • 185
0

The content of the allocated block is not defined and so it is implementation specific.

Some implementations (like this one you are using) set it to zero, others to 0xdeadbeef or some other magic number (msvc++ compiled malloc fills it with 0xCC but not everything).

It is implementation specific and so undefined, do not depend on it.

And do never reallocate memory inside memory just because it is dangerous.

Quonux
  • 2,975
  • 1
  • 24
  • 32
0

In multi-user operating systems, when memory is given to a process by the operating system, the operating system will typically clear the memory so that it does not reveal data that was previously there from other processes. (Of course, the system does not have to zero this memory; to protect privacy, it merely has to set the memory to any values that do not contain private data. Zero is usually used.)

This implies that when malloc returns memory that is freshly obtained from the operating system, which of course happens when the pool of memory malloc had previously is insufficient to satisfy your request, that memory will contain zeros. However, when malloc returns memory that was previously used by your process, it may contain other data. (Some of this data may be from parts of your program that are not normally visible to you, such as the C run-time initialization code or dynamic loaders and linkers.)

Since this behavior is a result of your operating system and not of the C specification, you may not rely on it when basing software only on the C specification. When you do not have assurance that this behavior will occur, you must write software as if every malloc could return uninitialized data, even if experience or examinations often show otherwise.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312