Reputation: 13
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
int data;
struct node * next;
};
int main() {
struct node * head = (struct node * ) malloc(sizeof(struct node));
head -> data = 10;
head -> next = (struct node * ) malloc(sizeof(struct node));
head -> next -> data = 20;
head -> next -> next = NULL;
int noOfNodes = 2;
char * buff = malloc(50);
strncpy(buff, (char * ) & noOfNodes, sizeof(int));
// strncpy(buff+4,(char *)head,sizeof(struct node *));
memcpy(buff + 4, (char * ) head, sizeof(struct node * ));
printf("noOfNodes: %d\n\n", *(int * ) buff);
printf("1]<%p><%d>\n", head, head -> data);
printf("2]<%p><%d>\n\n", ((struct node * ) buff + 4), ((struct node * )(buff + 4)) -> data);
printf("address of next node \n");
printf("3]<%p>\n", head -> next);
printf("4]<%p>\n", ((struct node * )(buff + 4)) -> next);
return 0;
}
Ouput:
noOfNodes: 2
1]<0x56450bd632a0><10>
2]<0x56450bd63320><10>
address of next node
3]<0x56450bd632c0>
4]<(nil)>
why there is difference in address ?
1] ends with ...2a0
2] ends with ...320
if address is different then how come it pointing to the variable data(...->data) correctly ?
why is (buff+4)->next is NULL? it should be same as head->next (i.e. <0x56450bd632c0>).
struct node *n1 = head;
when we do this irrespective of how large the struct node this only needs 8bytes to store(as we are storing address of struct node).
i want to do this using memcpy()
(using only 8 bytes)store only the address of struct node head
and not all struct node
in (buff+4).
how to do this ? thats why i used (struct node *
).
Upvotes: 1
Views: 81
Reputation: 61498
why there is difference in address ?
Because the buff
array is a different chunk of memory from the one that was malloc
ed for the head
, so buff+4
is a different place in memory.
if address is different then how come it pointing to the variable data(...->data) correctly ?
Because you memcpy
d some memory into the buff
at that location, copying it from the memory that head
points at. So although it is a different chunk of memory, it has the same data written into it.
why is (buff+4)->next is NULL?
Because you did not copy enough memory, so the part where the next
member should be is still whatever was in that part of the buff
before the copy. This happened because you told memcpy
to copy as much memory as a struct node *
takes up; but you didn't want to copy a chunk of memory that was a pointer, you wanted to copy a chunk of memory that was the node itself. So it should have said sizeof(struct node)
instead of sizeof(struct node *)
.
The struct node
structure starts with int data
, and int
might be the same size as any ordinary pointer (at least, I can't think of any situations where it would be bigger). So when we look at the memory that starts at the location buff + 4
, it seems we copied enough data there to put the correct value into the ->data
, but not enough to do anything about the ->next
.
Upvotes: 2
Reputation: 17638
[tl;dr] To copy the entire *head
to buff+4
the memcpy
line needs to be changed as follows.
memcpy(buff+4, (char *)head, sizeof(struct node)); // instead of sizeof(struct node *)
With OP's code, assuming the likely case of 32b integers and 64b pointers:
struct node
is padded to satisfy the pointer alignment requirements
struct node
{
int data;
int hidden_padding_field; // <--- inserted by the compiler
struct node *next;
};
the following copies 8 bytes from head
to buff+4
, meaning head->data
and hidden_padding_field
get copied, but head->next
does not.
memcpy(buff+4, (char *)head, sizeof(struct node *));
Consequently, the data
value gets copied correctly, but the next
pointer is left unitialized. That it happens to be NULL is entirely by accident, just one possible manifestation of undefined behavior.
Upvotes: 2