2

I am trying to print the size of pointers in both the cases. For both the cases I am getting 8 16 as output.

#include <stdio.h>

struct Book
{
    char name[10];
    int price;
};

int main(void)
{
    struct Book a;      // Single structure variable
    struct Book* ptr;   // Pointer of Structure type

    ptr = &a;

    struct Book b[10];  // Array of structure variables
    struct Book* p;     // Pointer of Structure type

    p = &b;

    printf("%ld %ld\n",sizeof(ptr),sizeof(*ptr));
    printf("%ld %ld\n",sizeof(p),sizeof(*p));

    return 0;
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Ajay
  • 21
  • 1
  • 4
  • 1
    Ajay, what do you intend those separator lines to signify at the end of your post? Please remove that distraction. Especially if you only inserted them to get around the system telling oyur that you have too much code in your question without accompanying prose explanation. – Yunnosch Jul 06 '20 at 15:15
  • 2
    Apart from all the buzz, there's an incompatible assignment operation going on in your code, i.e `p = &b;`. You are assigning the address of an `array of structure vars` to a `pointer to structure var`. Just do `p = b;`. – Shubham Jul 06 '20 at 16:00

2 Answers2

2

First of all, sizeof operator yields a type size_t, you must use %zu to print that.

Then, usually in any architecture, the size of a pointer is always constant, irrespective of the type they point to. In other words, a pointer needs to hold a memory location, and for any normal architecture, the address (of a memory location) has a fixed size. So, the size of any pointer, is same.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Pointer sizes are always the same, with the exception of function pointers, which may be greater, right? – Fiddling Bits Jul 06 '20 at 15:09
  • @FiddlingBits Well, there's no norm, but yes, that's the practical thing. Added a line to clarify. – Sourav Ghosh Jul 06 '20 at 15:10
  • @FiddlingBits What is `with the exception of function pointers`? I've read it everywhere that `sizeof(pointers)` is always same on any machine, regardless of the data type which it points to. Even after reading your comment, I checked it and I found (on my system), that `sizeof a function pointer to int` and `sizeof a pointer to int` are same. – Shubham Jul 06 '20 at 15:29
  • @FiddlingBits Can you please explain? That would be helpful for me to understand the scenario. – Shubham Jul 06 '20 at 15:29
  • 2
    @FiddlingBits *Pointer sizes are always the same, ...* No. [**Are there any platforms where pointers to different types have different sizes?**](https://stackoverflow.com/questions/916051/are-there-any-platforms-where-pointers-to-different-types-have-different-sizes) – Andrew Henle Jul 06 '20 at 15:30
  • It is pointer-to-members that are usually different, pointers to free functions are usually the same as any other pointer. – SoronelHaetir Jul 06 '20 at 15:43
  • Why does the op get `8 16` also in the second print? It sounds strange to me. – Roberto Caboni Jul 06 '20 at 15:53
  • @RobertoCaboni Which part is strange? – Shubham Jul 06 '20 at 16:22
  • @Lucas It's my understanding that if a system has much more flash than RAM, a function pointer may be larger. For example, a system with less than 0x100000000 RAM and more than 0xFFFFFFFF flash may require a RAM pointer of 32-bits and a function pointer of 64-bits. I could be totally wrong. – Fiddling Bits Jul 06 '20 at 17:01
  • 1
    @Lucas: With respect to C, the only requirements are that `char *` and `void *` have the same size and alignment, that pointers to qualified types have the same size and alignment as pointers to their unqualified equivalents, that all pointers to `struct` types have the same size and alignment, and that pointers to all `union` types have the same size and alignment. While different pointer types may have the same size on hardware like x86, that's not guaranteed and should not be relied upon. – John Bode Jul 06 '20 at 21:32
  • Ultimately, `sizeof char* = sizeof void* = sizeof qualified_types * = sizeof non-qualified_types* = sizeof struct* = sizeof union*` on x86. Then what's this about, _"that's not guaranteed and should not be relied upon"_. @JohnBode – Shubham Jul 07 '20 at 01:54
  • @Lucas - x86 is only one architecture of many. Historically there have been architectures where `sizeof (char *) != sizeof (int *)`. You shouldn’t make any assumptions beyond what the language definition guarantees (without good reason, anyway). – John Bode Jul 07 '20 at 03:44
  • @JohnBode Can I get some of the names? – Shubham Jul 07 '20 at 04:17
  • @Lucas: Check the link in Andrew Henle’s comment above. – John Bode Jul 07 '20 at 11:25
0

Is this what you want, in the second case:

printf("%zu %zu\n", sizeof(p1), sizeof(*p1));
// Output
8 160

Okay! Let's start from the beginning.

As Sourav Ghosh stated in his answer, "A pointer needs to hold a memory location, and for any normal architecture, the address (of a memory location) has a fixed size. So, the size of any pointer is the same.", regardless of its data type which it points to.

Now coming to your problem, consider and try to understand this modified version of your program:

#include <stdio.h>

struct Book
{
    char name[10];
    int price;
};

int main(void)
{
    struct Book b[10];  // Array of structure variables
    struct Book* p;     // Pointer to type struct Book
    struct Book (*p1)[10]; // Pointer to type struct Book[], which is array of type struct Book

    p = b; // same as p = &b[0] but not as p = &b
    p1 = &b; // this is how assignment of a pointer to array is done

    printf("%zu %zu\n", sizeof(struct Book*), sizeof(struct Book));
    printf("%zu %zu\n",sizeof(p),sizeof(*p));
    printf("%zu %zu\n",sizeof(p1),sizeof(*p1));

    return 0;
}

Output:

// perhaps on your PC
8 16
8 16
8 160
// on my PC
4 16
4 16
4 160

You see in the output that sizeof(struct Book), sizeof(p), and sizeof(p1), all are the same. Thus, size of any type of pointer is the same.

But when you are printing the size of the struct Book, i.e. you are asking the compiler, "tell me how much bytes of memory this struct Book contains",

for the first two cases (sizeof(struct Book) or sizeof(*p)), it is 16 and for the last case it is 160 which is size of 10 variables of type struct Book.

And if you're wondering why 16 as the size of a variable of type stuct Book, that's because of the 2 padding bytes in between the char and int member.

Read this SO question about padding and packing in structures.

Shubham
  • 1,153
  • 8
  • 20