14

I know that calloc request memory to be used, writes 0 on all the bits and then returns a pointer to it.

My question is: if I use calloc with a structure that contains pointers, will those pointers have the NULL value or do I have to set them to point to NULL?

struct a{
char * name;
void * p;
}* A;

So basically, will name and p point to NULL after I've used calloc with struct a?

Thanks!

Mihai Neacsu
  • 2,045
  • 5
  • 23
  • 37

3 Answers3

28

Somehow you've gotten a lot of incorrect answers. C does not require the representation of null pointers to be all-zero-bits. Many people mistakenly think it does, since an integer constant expression with value 0, converted to a pointer, becomes a null pointer.

With that said, on all real-world systems, null pointers are all-zero-bits, and calloc is a perfectly reasonable way to get a null-pointer-initialized pointer array in the real world.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 3
    +1: the only answer I've seen that's even close to right. I believe some IBM and Unisys systems use null pointers in which not all bits are zero. For that matter a x86 can as well -- a segment value of 0 gives a null pointer, regardless of the offset. All bits zero will work, but other null pointer values are possible as well. – Jerry Coffin May 02 '11 at 13:28
  • Just because some nonzero segment:offset pointer can evaluate to the same as linear address zero, I would not call it a "null pointer". A C compiler would have to go to generate code to perform costly extra work to check null pointers if you were to call these null pointers, and it would not improve the quality of the implementation since only the representation created by the compiler need be treated as a null pointer by the code it generates (null pointers never arise from arithmetic, only from constant expressions). – R.. GitHub STOP HELPING ICE May 02 '11 at 13:35
  • Actually the *only* reasons I can think of to use non-all-zero-bits for the null pointer are (1) if address 0 needs to be addressable, or (2) if you want null pointer dereference to generate a trap, and address 0 does not generate a trap, but some other address does. It's *always valid*, regardless of the hardware, to make a C implementation where null pointers are all-zero-bits, and thus, short of any compelling reason not to, implementors should always use all-zero-bits as the null pointer representation. – R.. GitHub STOP HELPING ICE May 02 '11 at 13:37
  • @R. Not so. It's not a matter of evaluating to the same linear address. Part of how Intel defines protected mode is that segment 0 can't be dereferenced (there is *no* linear address associated with it). No costly extra work would be needed -- it just has to check the segment part and ignore the offset. – Jerry Coffin May 02 '11 at 13:38
  • @R. You can argue about how things should be all you want -- it won't change how things really are. – Jerry Coffin May 02 '11 at 13:39
  • @Jerry: I'm talking about the code a compiler generates for `if (ptr)`, not what the machine has to do. This is completely up to the compiler, but supporting multiple aliases for the null pointer will be a huge waste of time and has no benefits. – R.. GitHub STOP HELPING ICE May 02 '11 at 13:48
  • @R. Read what I said. The compiler only has to test the segment, so it takes *no* extra time. Yes, it can have benefits -- it's been used (for one example) to pass a parameter to the exception handler "for free". – Jerry Coffin May 02 '11 at 14:04
  • Your statement about *real-world systems* needs a caveat or it would be incorrect. More about exotic NULL pointers at cfaq: http://c-faq.com/null/machexamp.html – u0b34a0f6ae Nov 15 '11 at 13:35
20

R.'s answer is good, but I'd like to add the standard quotes to support this, and show a way to 0 initialize your struct that does, in fact, yield NULL pointers.

From N1548 (C11 draft)

7.22.3.2 The calloc function allocates space for an array of nmemb objects, each of whose size is size. The space is initialized to all bits zero.[289]

The footnote then says (emphasis added):

Note that this need not be the same as the representation of floating-point zero or a null pointer constant.

While a null pointer is usually represented as all 0 bits, this representation is not guaranteed. To answer your question directly, no you cannot rely on the calloc()'d struct's pointers to be NULL.


If you want to set all contained pointers of a dynamically allocated struct to NULL you can use the following:

struct a *s = malloc(sizeof *s);
*s = (struct a){0};

C11:

6.7.9.21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, [...] the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration

and

6.7.9.10 ... If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;

C requires you to have at least one element inside the braces, which is why I use {0} instead of {}. The rest of the elements are initialized according to the above rules, which results in null pointers. As far as I can tell, the rules for this are the same in C11 and C99.

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
-5

The ISO C standard for calloc requires it to initialize everything to 0. That means that if you end up veiwing memory allocated by calloc as pointers, it will indeed initially contain NULL (0) pointers.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134