-2

Im new to community this is my first post so hello to everyone.

I have recently started studying the coding and c language in specific.But i have a confusion when it comes to structures and how they are referenced in memory.

This is example when my lack of understanding makes me unable to understand what exactly happening in code.

For example when asking malloc for space for lets say a node structure the way i understood it until now is that computer will allocate memory of size of struct if instructed by size of operator in parenthesis. Therefore that many memory locations will be allocated starting at specific location pointer points to.But when we use pointer of struct type we allocated memory for (in this case struct node) it just stores a address of first byte of said struct as all pointers do if i understand correctly.

Then when

`*(pointername).exactfieldname

For example if we assume there is node structure defined in code.With two fields for int called numbers and for pointer called next.

node *n=malloc (sizeof(node));
 *(n).next=malloc (sizeof(node));

syntax is used i cant understand how it works exactly.How is a computer just through pointer to a first byte out of certain number of bytes that were allocated suddenly able to access fields of structure?

Reason this is additionally confusing is because when defining a node struct for linked list for example it is possible to define pointer to struct of struct type being defined before it is defined because its just a pointer so it only stores address. Due to that fact struct pointer cant have any special property allowing it to access fields its still just a pointer right?

When pointer is derefrenced does it mean that computer goes to pointed location and enters a strucutres. And then rest of syntax after dereferencing pointer like *(pointer ).fieldname can be used because now computer is inside structure and interacts with it and .fieldname refers to that instruction now?

  • 2
    Hi, welcome to SO. The core of any question here should be *code*, not prose. If you provided a minimal, runnable example we could more accurately and easily discuss your questions. Maybe you could add a simple example – erik258 Sep 29 '22 at 12:09
  • Will edit thank you @erik258 – 21CenturyBoy Sep 29 '22 at 12:10
  • The base pointer gives you the address the struct, and the fields within that struct are offsets from that base pointer. The offsets are based on the sizes of the members of the struct. There's nothing at the memory address that indicates how to interpret the data there. – Welbog Sep 29 '22 at 12:10
  • "it just stores a address of first byte of said struct as all pointers do" The compiler also know the type of the pointer and hence also the size and location of fields in a struct. – Gerhardh Sep 29 '22 at 12:11
  • 2
    "Then when *(pointername).exactfieldname syntax is used" That should be `(*pointername).exactfieldname` or more readable `pointername->exactfieldname` – Gerhardh Sep 29 '22 at 12:12
  • 1
    See [How do pointer-to-pointers work in C? (and when might you use them?)](https://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c-and-when-might-you-use-them), https://stackoverflow.com/questions/41685123/understanding-c-pointers, https://stackoverflow.com/questions/39338921/understand-pointers-in-c, etc – Welbog Sep 29 '22 at 12:13
  • @Gerhardh ''it just stores a address of first byte of said struct as all pointers do" The compiler also know the type of the pointer and hence also the size and location of fields in a struct. '' Thank you for clarification.But my confusion is no how does a compiler know the type of fileds a struct pointer point to has if when defining inside a node a pointer to struct of same type its possible before struct being even defined? Doesn't that imply that since its possible pointers are seen as just storing addresses of certain location therefore type of pointer doesn't matter? – 21CenturyBoy Sep 29 '22 at 12:18
  • All pointers to `struct` types have the same representation and the same size. The `struct` type does not need to be fully defined to derive a pointer type from it, and that pointer type will be fully defined, so it is OK for a `struct` type to have members with the derived pointer type. – Ian Abbott Sep 29 '22 at 12:30

2 Answers2

2

I'll try to answer despite your question lacking some clarity. If I get you right, you are confused by this:

typedef struct node {
   struct node *next;  // <<<< here
   some_type_t data;
} node;

In the line marked, the compiler does not yet know what struct node looks like. That is correct. It doesn't need to know that because we only store a pointer.

In that place you cannot define a non-pointer element of that type (or any other incomplete type) for exactly that reason.

Now if you come to that part:

   node *n=malloc (sizeof(node));
   n->next=malloc (sizeof(node));

(Note: Your syntax was incorrect)

You seem to wonder how the compiler would know what n->next really is as it was unknown when the struct was defined. That does not matter. It is known when the compiler comes to this line. You can only dereference a pointer if the type is fully known in that location. The compiler now knows what node* means and can address the fields in *n and in the same way it can deal with n->next.

Gerhardh
  • 11,688
  • 4
  • 17
  • 39
0

Study and try do understand the following code. Compare the values that are printed out. %p will print address values (hex format) and %d prints decimal values. Take a good look at the parameters that are passed to the printf function. & is the 'address of' operator and -> is a dereference operator, which is equal to *(pointer)..

struct node {
    struct node *next; //pointer to struct node
    struct data_rec {  //embedded struct
        int value;     //some value of type int
    } data;            //data of type struct data_rec
};

//allocation on the heap -> pointer to struct node
struct node *allocated_node = malloc(sizeof(struct node));
allocated_node->next = NULL;
allocated_node->data.value = 0;

//allocation on the stack (sizeof(struct node) bytes)
struct node base_node;
base_node.next = allocated_node;
base_node.data.value = 42;

//prints some information of the node
void printNodeInfo(struct node *node_)
{
    printf(
        "address of node:            %p\n"
        "address of node.next:       %p\n"
        "value   of node.next:       %p\n"
        "address of node.data:       %p\n"
        "address of node.data.value: %p\n"
        "value   of node.data.value: %d\n",
         node_,
        &node_->next,
         node_->next,
        &node_->data,
        &node_->data.value,
         node_->data.value
    );
}

int main()
{
    printNodeInfo(&base_node);
    printNodeInfo(allocated_node);
    return 0;
}
Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11