0

When I dynamically allocate memory in C with a function of the malloc family is there some rule (coming from the C standard or the inner workings of an OS) as to what the initial value of that memory is?

int* ptr = malloc(sizeof (*ptr));
bool b = *ptr == 0;  // always true?
trincot
  • 317,000
  • 35
  • 244
  • 286
hgiesel
  • 5,430
  • 2
  • 29
  • 56
  • 4
    Nope. `calloc`? Yes. – user3386109 May 05 '16 at 02:59
  • 2
    depends. Wouldn't depend on it. You can always use `calloc`. http://stackoverflow.com/questions/1538420/difference-between-malloc-and-calloc – George Stocker May 05 '16 at 02:59
  • @MikeCAT: As far as I can tell, using the result of `malloc()` without initialization is only undefined behavior on systems that use "trap representations", which when the types involved are integral as in the question here, basically does not happen in any real system. So while it may technically be undefined behavior on some hypothetical computer, I do not think there is any risk of true UB in the code in this question. It's still useless code. – John Zwinck May 05 '16 at 03:07
  • for this line: `bool b = *ptr == 0;` the resulting value in `b` will depend on the `precedence` priority in C of the two operators `=` and `==` Per: `http://www.swansontec.com/sopc.html`, the assignment operator `=` has a lower precedence than the binary operator `==`, so it would depend on what happened to be in memory at `*ptr` Since that pointer has `int*` type, (lets assume a 32 bit architecture) the chances of `*ptr` being 0 are 1:4gig against. So most likely the result in `b` will be false, However, there is that 1 in 4gig chance the result in `b` will be true – user3629249 May 07 '16 at 02:14

1 Answers1

5

The initial value of dynamically-allocated memory is indeterminate as far as the C standard is concerned. Some platforms may happen to give you zeros, others may happen to give you guard values like 0xEE everywhere, but none of this can be relied upon in a portable C program.

If you need zeros, the most conventional way is to use calloc(), which has a chance of being optimized on some platforms.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • The problem with `calloc` is that is zeroes the memory, but does not guarantee e.g. to set an array of pointers to _null pointer_ if the _null pointer_ value is not zero, too. So this also not portable. The same for floating point and complex. – too honest for this site May 05 '16 at 03:04
  • @Olaf: For float and double, C99 guarantees that `calloc()` will create 0.0 values if `__STDC_IEC_559__` is defined, aka if the system uses IEEE 754. So it's easy to add a compile-time check for that, and it is extremely likely that it will pass on any system anyone here uses. So not theoretically portable, but possible to ensure correctness anyway. – John Zwinck May 05 '16 at 03:10
  • No, not every system uses IEEE754 floating point. Actually a large set of systems don't use it, or only partially implement it. But I agree, that most of these systems also use all-zero for `0.0`. You forget about embedded systems and DSPs. But floats were not the only issue and for a pointer it is more complicated to have a check, because any cast of `0` to a pointer has to match `NULL` by definition. Anyway, none was the point. I explicitly was after portability, which you also mentioned, which is actually also not guaranteed with `calloc`. It is something one has to keep in mind. – too honest for this site May 05 '16 at 03:17