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?
CodePudding user response:
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
.
CodePudding user response:
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;
}