2

So I've read the documentation for calloc and it says that it will initialize n objects of size size and initialize each of them to 0.

So before making my implementation of a generic dynamic array in C I decided to make it with int type to make things simpler. I used to call calloc and every integer in the buffer would be initialized as 0 meaning an empty space. But when I changed the data buffer from int *buffer to void **buffer I've been wondering if this properly initializes every void pointer to NULL. I've seen NULL being cast to 0 if you do int a = NULL but does void *p = 0 the same as void *p = NULL? And is this what calloc actually does?

  • In the end, everything is just a number and is stored as such. So the memory at this point would be 0. The other thing is how it is evaluated and in this case if you accessed this pointer you would have a NULL pointer. There are also [different implementations of NULL](https://stackoverflow.com/q/1296843/9232218) – Yastanub Nov 22 '18 at 18:31
  • 2
    @Yastanub *The other thing is how it is evaluated and in this case if you accessed this pointer you would have a NULL pointer.* – No, there is no guarantee that `NULL` is the same as all zeros at all. – Swordfish Nov 22 '18 at 18:34
  • @Swordfish yup, duplicate, not sure why I couldn't find that question after an hour of searching. Thanks! –  Nov 22 '18 at 18:37
  • @LeoVen Then you really have to work on your [Google-fu](https://www.google.com/search?q=calloc+and+null&) – Swordfish Nov 22 '18 at 18:51
  • @Swordfish My google-fu abilities are doing pretty well considering that the title is pretty lame and has nothing to do with what I was actually looking for. I just hope that my question fills another gap where questions like [this one](https://stackoverflow.com/questions/29800636/calloc-and-null) fails to do. –  Nov 22 '18 at 19:27
  • @LeoVen Didn't mean to offend you! – Swordfish Nov 22 '18 at 19:31

2 Answers2

3

NULL is guaranteed not to point to anything. All calloc does is zero-fill memory after malloc.

"A null pointer is conceptually different from an uninitialized pointer. A null pointer is known not to point to any object or function; an uninitialized pointer might point anywhere. See also questions 1.30, 7.1, and 7.31."

"As mentioned above, there is a null pointer for each pointer type, and the internal values of null pointers for different types may be different. Although programmers need not know the internal values, the compiler must always be informed which type of null pointer is required, so that it can make the distinction if necessary (see questions 5.2, 5.5, and 5.6)."

http://c-faq.com/null/null1.html

hellork
  • 324
  • 2
  • 8
  • 1
    Something interesting: Have seen already `void(*reset)(void) = NULL; reset();` for a software system reset on some micro controller (can't remember which one it was, possibly AVR). Obviously not standard compliant - to be so, NULL would need to differ from the starting address, it might have been assigned all bits 1 then... – Aconcagua Nov 22 '18 at 19:18
0

First, a note: The standard doesn't actually specify that the NULL pointer is bitwise equal to zero, just that NULL doesn't point to anything. In most implementations, however, NULL is bitwise equal to 0.

void *p = 0 will set p to the pointer consisting on only 0's. While on your machine this might be the same as void *p = NULL, this is not guaranteed by the C standard.

void **buffer = calloc(...) will set each void *p in buffer to 0, which might corresponds to NULL on your machine.

let's look at calloc(3, 4), on a machine where integers and void pointers are both 4 bytes. (Note that integers and void pointers are not always 4 bytes; this is only for demonstrative purposes.) calloc would in this case allocate:

| 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |

and return a pointer to the above memory (the numbers represent the value stored in the memory in hexadecimal).

if we do int *buffer = calloc(3, 4), each 4 bytes of buffer would be an integer with value 0.

if we do void **buffer = calloc(3, 4), each 4 bytes of buffer would instead be a void* pointing to address 0. On machines where NULL is bitwise 0, this would be the same as filling buffer with NULL pointers.

CoffeeTableEspresso
  • 2,614
  • 1
  • 12
  • 30