Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reason for seemingly inconsistent sizes of pointers and struct types?

On my machine, the relevant sizes are:
sizeof(char) == 1, sizeof(int) == 4 and sizeof(char*) == 8.

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

typedef struct person{
    char *name;
    int age;
}Person;

int main()
{
    printf("sizeof(Person): %d\n", sizeof(Person)); //-> 16 bytes
    Person *person = (Person*)malloc(sizeof(Person));
    printf("sizeof(person): %d\n", sizeof(person)); //-> 8 bytes ( Why 8 and not 16? )

    char buffer[32];
    printf("sizeof(buffer): %d\n", sizeof(buffer)); //-> 32 bytes
    person -> name = (char*)malloc(sizeof(buffer));
    printf("sizeof(person->name): %d\n", sizeof(person->name)); //-> 8 bytes ( Why 8 and not 32? )

    return 0;
}

I know that sizeof(Person) == 16 because of padding, but I don't understand the following.
If sizeof(Person) == 16, why sizeof(person) == 8 and not 16?
And if sizeof(buffer) == 32, why sizeof(person->name) == 8 and not 32?

like image 705
BUG Avatar asked Dec 01 '20 13:12

BUG


2 Answers

Because, as sizeof(char *), sizeof(person) returns the size of a pointer. And in your case, a pointer to a struct (here to a Person struct) is of size 8.

And sizeof(person->name) returns the size of a pointer on a char as name is defined as a char *.

buffer is not a pointer, it is an array. The compiler knows it and sizeof(buffer) returns the size of the array, even through there is some similarities between the name of an array and a pointer, they are not treated the same.

like image 151
Puck Avatar answered Oct 15 '22 12:10

Puck


For starters to output an object of the type size_t you shall use the conversion specifier zu

printf("sizeof(Person): %zu\n", sizeof(Person));
                        ^^^   

I don't understand the following: If sizeof(Person) == 16, why sizeof(person) == 8 and not 16?

The name Person denotes the structure

typedef struct person{
    char *name;
    int age;
}Person;

An object of this type occupies 16 bytes.

The name person declared like

Person *person = (Person*)malloc(sizeof(Person));

denotes a pointer. This pointer occupies 8 bytes and points to a memory allocated for an object of the type Person that occupies 16 bytes.

That is sizeof( Person ) and sizeof( Person * ) that is equivalent to sizeof( person ) are two different expressions.

And if sizeof(buffer) == 32, why sizeof(person->name) == 8 and not 32?

Again the name name has a pointer type and occupies 8 bytes. It is a data member of the structure person declared like

char *name;

This pointer points to a dynamically allocated memory that occupies 32 bytes.

Pay attention to that the size of a pointer does not depend on whether it points to a single object or to the first element of an array. That is you can allocate memory for a very big array but nevertheless the size of the pointer pointing to the allocated memory will not be changed depending on the size of the allocated memory.

Consider for example

int a[10];

int *p = a;

int b[10000];

int *q = b;

In this example the pointers p and q have the same size. You could write for example

int a[10];

int *p = a;

int b[10000];

p = b;

The size of the pointer p will not be changed after the last assignment.

like image 25
Vlad from Moscow Avatar answered Oct 15 '22 10:10

Vlad from Moscow