11

I was trying to remember the basics of C programming, and regarding pointers to structures I was doing the following:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main()
{
    struct MyStruct {
        int number;
        char *name;
    };

    int i;

    struct MyStruct *p_struct = (struct MyStruct *) malloc(sizeof(struct MyStruct)*3);
    printf("sizeof(struct MyStruct) = %d\n", sizeof(struct MyStruct));

    for (i = 0; i < 3; i++)
    {
        p_struct->number = i;
        p_struct->name = "string";
        printf("p_struct->number = %d, p_struct->name = %s\n", p_struct->number, p_struct->name);
        ++p_struct;
    }

    printf("sizeof(p_struct) = %d\n", sizeof(p_struct));
    free(p_struct);
    return 0;
}

My question is: I get 8 bytes as the size of the structure, which is okay as 4+4 = 8 bytes due to alignment/padding of the compiler, but why do I get 4 bytes from sizeof(p_struct)?

I was expecting to get 24 (8 bytes x 3), why is this so?

If this is correct, can I get the total allocated size of 24 bytes somehow?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
c_b
  • 111
  • 1
  • 1
  • 4
  • Note that in this simple example, it is not required to use `malloc` to allocate your structure. You can (and should) allocate your data on the stack whenever possible. To allocate a struct on the stack, just declare a variable `struct MyStruct myStruct;`. Data allocated on the stack are automatically freed, no need to call `free` explicitely. – Vincent Robert May 20 '14 at 13:57
  • Absolutely, the point is I was practicing dynamic memory allocation - that's why I especially used malloc. – c_b Jan 30 '15 at 23:37

3 Answers3

15

No, the size of the structure is eight bytes because you have two four-byte fields in it, try printing sizeof(int) and sizeof(char *) and see for yourself.

When you do sizeof of a pointer, you always gets the size of the pointer and never what it points to. There is no way (in standard C) to get the size of memory you have allocated with malloc.

Also note that you have undefined behavior in your code, as you change the pointer p_struct so it no longer points to what your malloc call returned. This leads to the undefined behavior when you try to free that memory.


There's also another undefined behavior in the code: The sizeof operator returns a value with the type size_t. To print a size_t value with printf one need to use the %zu format specifier. Mismatching format specifier and argument type leads to said UB.

Also, the size of pointers and almost all other types are dependent on the compiler and target platform. These days, with 64-bit systems, pointers usually are 64 bits wide, which is 8 bytes. So with padding the structure would be 16 bytes if targeting a 64-bit system.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks, i know the reason for eight bytes but was not aware of the undefined behavior. I guess I need to revert p_struct back to the beginning of the area that was allocated with malloc and then free it. Can you explain the size of the pointer here then, why do I get 4 bytes for example? – c_b May 26 '14 at 21:29
  • sizeof(MyStruck->ThatThisStruct) not work is impossible that I had 6200 register.. –  Mar 15 '17 at 18:05
6

Pointers are always the same size on a system no matter what they're pointing to (int, char, struct, etc..); in your case the pointer size is 4 bytes.

Clinton Pierce
  • 12,859
  • 15
  • 62
  • 90
  • 2
    That's generally not correct. There are implementations where different pointers have different sizes. – gnasher729 May 20 '14 at 13:39
  • 1
    Generally, it *is* correct. There are specific and unusual circumstances where it's not, but generally is is correct. – Clinton Pierce May 20 '14 at 14:11
  • 5
    There are implementations where they have different sizes indeed, but these are pretty rare, these days. I assume the original poster is not learning on such a machine. – Rudy Velthuis May 20 '14 at 14:49
0

p_struct is a pointer to a struct. Pointers usually take either 4 or 8 bytes. If you wanted to know the size of the struct itself, you would use sizeof (*p_struct).

Note that your code is likely to crash, because you increased p_struct three times, and then call free () on the result, not on the original pointer that malloc returned. Much clearer and safer to write for example

for (i=0; i<3;i++)
{
    p_struct [i]->number = i;
    p_struct [i]->name = "string";
    printf("(*p_struct).number = %d, (*p_struct).name = %s\n", p_struct [i]->number p_struct [i]->name)
}
gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Thanks, I know. I used the same loop before but I wanted to especially do pointer arithmetic. But I understand why the code is not stable, I will revert the pointer back 3 times to avoid it. What is the difference between sizeof(p_struct) and sizeof(*p_struct) then? – c_b May 26 '14 at 21:29