3

Hi I have the below code to create the linked list

#include<stdio.h>
#include<stdlib.h>
struct node{
        unsigned int data1;
        unsigned int  data2;
        struct node *ptr;
}obj;
void enterData()                                                        // Here the EnterDAta fnnction uses the obj object to enter the data and note that this
{                                                                       // obj is used agauin and again in the every node of the list to enter the data
        printf("\n Enter the data1 ");
        scanf("%u",&obj.data1);
        printf("\n Enter the data2 ");
        scanf("%u",&obj.data2);
}
void append(struct node **start)                                        // This is used to append the dara un the list or also used to add the first element in the list
{
        enterData();
        struct node *next_node=*start;
        if(next_node==NULL)
        {
                printf("\nAdding first element in the list ......\n");
                next_node=malloc(sizeof(struct node));
                printf("\n The memory location of next_node is %p",&next_node);     
                if(next_node==NULL)
                {
                        printf("\n Out of Memory");
                }
                else{
                        next_node->data1=obj.data1;
                        printf("\n The memory location of next_node->data1 is %p",&next_node->data1);
                        next_node->data2=obj.data2;
                        printf("\n The memory location of next_node->data2 is %p",&next_node->data2);
                        next_node->ptr=NULL;
                        *start=next_node;                                               //This line of code here is modifying the header pointer see the magic of the pointer :)
                }
                printf("\n The first element added successfully");
        }
        else
        {
                printf("\n Appending the data ......\n");
                struct node *temp=next_node;
                next_node=malloc(sizeof(struct node));
                if(next_node==NULL)
                        printf("\n Out of Memory");
                else
                {
                        next_node->data1=obj.data1;
                        next_node->data2=obj.data2;
                        next_node->ptr=NULL;
                        while(temp->ptr!=NULL)
                                temp=temp->ptr;
                }
                temp->ptr=next_node;
                temp=NULL;
                printf("\n Data appended Successfully!!! ");

        }
next_node=NULL;
}
int main()
{
struct node *head=NULL;
append(&head);
return 0;
}

In the above code say if I get the memory address of next_node as 1000 then the memory address which I will get for the next_node->data1 is 1000 and the memory address of the next_node->data2 is 1004

But if in the above append function if just tweak some changes in the code like this

void append(struct node **start)                                        // This is used to append the dara un the list or also used to add the first element in the list
{
        enterData();
        struct node *next_node=*start;
        if(next_node==NULL)
        {
                printf("\nAdding first element in the list ......\n");
                next_node=malloc(sizeof(struct node));
                if(next_node==NULL)
                {
                        printf("\n Out of Memory");
                }
                else{
                        next_node->data2=obj.data2;
            printf("\n The memory address of next_node->data2 is %p ",&next_node->data2);
                        next_node->data1=obj.data1;
            printf("\n The memory address of next_node->data1 is %p ",&next_node->data1);
                        next_node->ptr=NULL;
                        *start=next_node;                                               //This line of code here is modifying the header pointer see the magic of the pointer :)
                }
                printf("\n The first element added successfully");
        }
        else
        {
                printf("\n Appending the data ......\n");
                struct node *temp=next_node;
                next_node=malloc(sizeof(struct node));
                printf("\n The memory address of next_node is %p ",&next_node);
                if(next_node==NULL)
                        printf("\n Out of Memory");
                else
                {
                        next_node->data1=obj.data1;
                        next_node->data2=obj.data2;
                        next_node->ptr=NULL;
                        while(temp->ptr!=NULL)
                                temp=temp->ptr;
                }
                temp->ptr=next_node;
                temp=NULL;
                printf("\n Data appended Successfully!!! ");

        }

Now if the address of next_node is 2000 then I get the memory address of next_node->data1 as 2004 and for data2 is 2008 but shouldn't it be the other way as we are first storing the data2 in the memory location using the next_node pointer ?

  • i doubt it would be different. In code block 2 you are printing the address of data2 followed by data1.Also in code block 2 you are not printing address of next_node in the if next_node is null block. can you run the program and show the exact result as output by program in the 2 cases? – Pradheep Jun 22 '15 at 17:02
  • when using printf() function, it is (usually) best to end the format string with '\n' as that will cause the output to be flushed to stdout. The leading '\n' in the current format strings causes the prior printf() to be displayed, not the current printf(). – user3629249 Jun 22 '15 at 17:15
  • function: append() has this line: 'printf("\n The first element added successfully");' However, if the malloc fails, then this printf() is still executed but the node was not added – user3629249 Jun 22 '15 at 17:20
  • function: append() when adding after the first node, if the malloc fails, then the code continues as if the malloc were successful. – user3629249 Jun 22 '15 at 17:25
  • function: main() after adding the first node, the code exits without cleaning up (I.E. without free'ing the malloc'd memory area(s)) suggest, before exiting, to loop through the linked list, passing each node to free() – user3629249 Jun 22 '15 at 17:27
  • @Pradheep In the code block 2 i have first stored the address of data2 in the memory block allocated by malloc. So I guess it is the data2 which should be stored first rt in that memory block ? – Astha Arora Jun 22 '15 at 17:31
  • You didn't store any address, you copied an `unsigned int` value from `obj` to the newly `malloc`ed struct, with `next_node->data2=obj.data2;` and it makes no difference whatsoever whether you copy `data1` before or after you copy `data2`. – Weather Vane Jun 22 '15 at 17:32
  • Yes rt i didn't store any address but i copied the data now the order in which i copied the data is different in both the cases then in second case data2 should be stored first than data1 rt ? – Astha Arora Jun 22 '15 at 17:44
  • 1
    I think you should take a step back and think about the comments and answers, instead of trying to refute them. – Weather Vane Jun 22 '15 at 17:48
  • I would suggest you should also print the address of `next_node->ptr` in second case. – haccks Jun 22 '15 at 17:54
  • you should read about memory alignment in the struct, means how your data is actually mapped in the memory – ThunderWiring Jun 23 '15 at 14:54
  • @ThunderWiring you have some good sources available for that ? –  Jun 24 '15 at 04:05
  • @ Rohit Saluja this question here: http://stackoverflow.com/questions/4306186/structure-padding-and-structure-packing could give you a good point to start. – ThunderWiring Jun 24 '15 at 09:31

1 Answers1

4

The relative addresses of the members of your nodes are a function of the layout of a struct node, not of the order in which you access them. If you swap the data1 and data2 members in the declaration of struct node then you will see data2 appearing at the lower address in every instance, but with the current declaration, data1 will appear first in every instance.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I think there is something inconsistent in the question anyway since in the first example the addresses are given as `1000` and `1000` and `1004`, but in the second example are `2000` and `2004` and `2008`. Where has the extra field at `2000` come from that has displaced the two `data` fields? – Weather Vane Jun 22 '15 at 17:13
  • @weatherVane Well i just took it for the understanding purpose Also the address would be in hex form . So your doubt is invlalid – Astha Arora Jun 22 '15 at 17:33
  • @john Bollinger Swapping the declaration of data1 and data2 in the structure will only effect the memory space of the structure object obj rt? When I create a memory block using malloc then it created a memory chunk of size equal to the size of the structure object rt ? Then in this memory chunk I am storing the value of data1 and data2. In the first snippet i have stored data1 first so data1 has address space less than data2 but in the second data2 is stored first then it should have address less than data1. – Astha Arora Jun 22 '15 at 17:40
  • Shouldn't the address in the malloc allocated memory space be dependent upon the order in which we store the value in that memory space. As using malloc we just create a chunk of memory of size equal to the size of stryct object – Astha Arora Jun 22 '15 at 17:42
  • @AsthaArora, no, the location at which a particular member is stored is *never* related to the order in which you perform the assignments. The `struct` declaration is essentially a map of how the members are laid out in memory. The fact that the structures are dynamically allocated has pretty much nothing to do with it. – John Bollinger Jun 23 '15 at 00:43
  • @AsthaArora, if the members were arranged in memory based on the order in which they were assigned to, then how would you later be able to tell which was which? – John Bollinger Jun 23 '15 at 00:44
  • @ John Bollinger **The relative addresses of the members of your nodes are a function of the layout of a struct node** Does this mean that the order in which we declare the member in the struct in that order only they will be stored in the memory allocated by malloc ? –  Jun 23 '15 at 04:54
  • @RohitSaluja, yes. However memory for an instance of your struct is allocated -- statically, automatically, or dynamically -- the members are *always* laid out identically within that memory, and that layout orders members in the same sequence that the `struct` declaration does. In some cases there may be padding between members or after the last one (but never before the first one). Identical layout is essential for instances to be usable, because often the code that accesses your structs won't know how they were allocated or initialized. – John Bollinger Jun 23 '15 at 17:56