3

What will be the output of the program on a 32-bit machine (using GCC)? Explain.

#include<stdio.h>

int main() {

     struct node {
         int data;
         struct node *link;
     };

     struct node *p, *q;
     p = (struct node *) malloc(sizeof(struct node));
     q = (struct node *) malloc(sizeof(struct node));
     printf("%d, %d\n", sizeof(p), sizeof(q));
     return 0;
}

The output shows

4, 4.

Is the above program related to structure member alignment padding and data packing?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
XOR
  • 314
  • 5
  • 11
  • Use `%zu` to print a `size_t`, and as pointed out by others, you are printing the size of a pointer, try: `printf("%zu, %zu\n", sizeof(*p), sizeof(*q));` – David Ranieri Jul 31 '15 at 07:55

4 Answers4

3

No, you are just printing the size of the pointers. It's not related to the internal member layout of structures.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
timrau
  • 22,578
  • 4
  • 51
  • 64
2

On a 32-bit system the stored addresses are always 32 bits big. If you're printing the size of a pointer you're basically just printing the size of the address it points to (32 Bit -> 4 Byte).

If you want to know the size of the struct do something like this:

struct node p;
struct node q = {4, &p};

printf("%zu, %zu\n", sizeof(p), sizeof(q));
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
muXXmit2X
  • 2,745
  • 3
  • 17
  • 34
2
  • Point 1 Use %zu format specifier to print the output of sizeof of type size_t .

  • Point 2 Note the type of p, it is struct node *, same as q.

So, essentially, sizeof(p) and sizeof(q) are exactly same as sizeof(struct node *), which, on your platform are 32 bit wide. As you're not considering a variable here, so the alignment and padding for the structure and members are neither relevant nor involved in this case.

That said, please see why not to cast the return value of malloc() and family in C.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • `%zu` will not necessarily work on every system, suggest OP the alternative to use `%lu` in that case. – Am_I_Helpful Jul 31 '15 at 08:08
  • @shekharsuman no, I won't. `§7.21.6.1`, paragraph 7 prevents me from doing that. :-) – Sourav Ghosh Jul 31 '15 at 08:17
  • Then I'd fluently award you a downvote. I've experienced this problem in Dev C++, Windows,32 bit. You should accept criticism, and happily apply that in your answer... – Am_I_Helpful Jul 31 '15 at 08:20
  • @shekharsuman you're most welcome. If i'm getting down-votes for advising the _correct_ thing, i'm more than glad. Cheers !! – Sourav Ghosh Jul 31 '15 at 08:21
  • If you're not providing an alternative to OP for the special cases too, and if being advised by someone which you should, then you're pretty much rude guy. If you ask as a proof, then I can give you a proof too. BTW, I just asked you to make an edit revealing the exceptional cases too. It again, depends on your will to improve the answer. – Am_I_Helpful Jul 31 '15 at 08:27
  • [O'Reily's Understanding and using C pointers](http://shop.oreilly.com/product/0636920028000.do) book says `The recommended format specifier is %zu. However, this is not always available. As an alternative, consider using %u or %lu.`. And, I feel you and me can't be more superior than him(the author). – Am_I_Helpful Jul 31 '15 at 08:28
  • @shekharsuman: The advice to use `%u` or `%lu` is dodgy at best. You'd have to fence it with `if (sizeof(size_t) == sizeof(int)) …use %u… else if (sizeof(size_t) == sizeof(long)) …use %lu… else …cry out in horror…`. Frankly, there's limited excuse for not following at least the 15+ year old C99 standard that added `%zu` (and preferably the 3+ year old C11 standard). The trouble is, MS is stuck in a 25+ year old time-warp w.r.t their C compiler. It really is beyond time that MS updated their compiler. – Jonathan Leffler Aug 01 '15 at 23:58
  • @JonathanLeffler-Thanks for your feedback, I appreciate this. But, my point was to simply check exactly what you mentioned using if-else and then apply `%lu` OR `%u` only if `%zu` is not available. I agree that MS compilers are crap. But, I just requested the author to add this line as a suggestion... – Am_I_Helpful Aug 02 '15 at 05:12
  • @SouravGhosh- I feel I have done a terrible thing as I should haven't downvoted your correct answer. But, I also feel you shouldn't have enlarged this issue. Nevermind though, I am retracting my downvote, THANKS to SIR Jonathan Leffler, and I again apologise for doing such a childisch act. SORRY for editing your answer to remove my downvote(my vote is locked). I hope you're no more angry over me, and I will keep upvoting your answers as usual... – Am_I_Helpful Aug 02 '15 at 07:45
0

No, it is not related to the structure member alignment padding and data packing.

Since it is a 32-bit machine the size of any pointer will be 4 bytes. Since p and q are of type struct node * i.e. pointer to struct node the result prints size of pointers p and q.

TryinHard
  • 4,078
  • 3
  • 28
  • 54