2

How's a struct allocated? When I try to print the address of struct and &struct, it gives me difference value. So that struct needs some byte to store something before store the variables inside?

This is my code.

#include <stdio.h>

typedef struct Point {
    int x;
    struct Point* net;
} Point;

int main()
{
    Point next;
    
    printf("1: %x \n", next);
    printf("2: %x \n", &next);
    return 0;
}

This is the result.

1: 5ffe80 
2: 5ffe90
  • 5
    Neither of your `prinf()` statements is correct. `next` is not an `unsigned int`, so using `%x` to print it invokes undefined behavior. There is **no** way to print a full `struct` with `printf()` the way you're trying to do - you need to print each element individually. And `&next` is also not an `unsigned int` - to print an address in full compliance with the C standard you need to use `%p` **and** cast the address to `void *`. – Andrew Henle Apr 22 '23 at 16:12
  • 1
    "How's a struct allocated?" allocation for structs is the same as for anything. A struct is just an ordered sequence of fields. "So that struct needs some byte to store something before store the variables inside?" no, a struct is just and ordered sequence of fields. – erik258 Apr 22 '23 at 16:15
  • https://stackoverflow.com/a/1597426/1726083 you might also want to review when a variable in C has a defined and undefined initial value. – erik258 Apr 22 '23 at 16:18
  • 2
    @erik258, allocation for structs is indeed the same as allocation for objects of any other type, but structs are *not* just a sequence of fields, at least not in the context of allocation. They may also contain unnamed padding between members and after the last member. – John Bollinger Apr 22 '23 at 16:21
  • 2
    The compiler should have issued some warnings. – Daniel Walker Apr 22 '23 at 16:30

2 Answers2

2

Your code has undefined behavior in both cases:

  • in printf("1: %x \n", next); you pass a structure where printf expects an unsigned int: This has undefined behavior.

  • in printf("1: %x \n", &next); you pass a pointer to a structure where printf expects an unsigned int. Same problem.

You observe different behavior, but anything could happen.

To print the value of a pointer, use this:

    printf("1: %p\n", (void *)&next);

When you pass the structure by value, you cannot print anything because printf does not handle this data type.

Structures are implemented by the compiler as blocks of sizeof(Point) bytes with the specified contents. Depending on the context, these blocks may be located in an area of the stack, or stored in one of more registers. If you allocate memory with malloc(), the block whose address is returned is guaranteed to have the required alignment to store any object type, including all structures.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
0
    printf("1: %x \n", next);

This is Undefined Behaviour, as printf() is assuming you are passing as a second argument. This results in interpreting the whole structure you are passing as an unsigned, which is not true, but is allowed (you will probably receive a compilation warning) because printf is a va_args function, in which the compiler cannot decide on the parameter list types because they are decided internally to printf() by scanning the characters of the format string.

    printf("2: %x \n", &next);

This is also Undefined Behaviour, but for a different reason: you are passing to the function a pointer with the address of the Point structure, and this is being interpreted as an unsigned, to print it's value in hexadecimal. You should have used %p to print the pointer value, and it should be correct. But in the first case you always pass the whole structure copied onto the function, and printf is interpreting that data as if you have passed just an unsigned. This can result in anything

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31