temp1284
temp1284

Reputation: 13

why there is difference in address but still pointing to the same data?

#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

Answers (2)

Karl Knechtel
Karl Knechtel

Reputation: 61498

why there is difference in address ?

Because the buff array is a different chunk of memory from the one that was malloced 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 memcpyd 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

dxiv
dxiv

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

Related Questions