动态内存分配的内存布局

3

你好,我有以下代码用于创建链表

#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;
}

在上面的代码中,假设我得到了next_node的内存地址为1000,则获取next_node->data1的内存地址为1000,获取next_node->data2的内存地址为1004。

但是,如果在上述附加函数中,将代码稍作更改,如下所示:

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!!! ");

        }

现在,如果next_node的地址为2000,则next_node->data1的内存地址为2004,data2的内存地址为2008。但是,由于我们首先使用next_node指针将data2存储在内存位置中,所以它不应该是另一种方式吗?

我怀疑这不会有所不同。在代码块2中,您正在打印data2的地址,然后是data1的地址。此外,在代码块2中,如果next_node为空,则不会打印next_node的地址。您能否运行程序并显示程序在两种情况下的确切输出结果? - Pradheep
当使用printf()函数时,最好在格式字符串的末尾加上'\n',因为这会导致输出被刷新到stdout。当前格式字符串中的前导'\n'会导致先前的printf()被显示,而不是当前的printf()。 - user3629249
函数:append() 有这一行代码:“printf(\n第一个元素已成功添加);”。但是,如果 malloc 失败,则仍会执行此 printf(),但节点未被添加。 - user3629249
函数:append() 当在第一个节点之后添加时,如果malloc失败,则代码将继续执行,就好像malloc成功一样。 - user3629249
1
我认为你应该退一步,思考一下评论和答案,而不是试图反驳它们。 - Weather Vane
显示剩余8条评论
1个回答

4
您的节点成员的相对地址取决于struct node的布局,而不是您访问它们的顺序。如果您交换struct node声明中的data1data2成员,则会在每个实例中看到data2出现在较低地址处,但是在当前声明中,data1将在每个实例中首先出现。

我认为问题中存在一些不一致,因为在第一个例子中,地址分别为 100010001004,而在第二个例子中分别为 2000200420082000 地址处的额外字段是从哪里来的?这导致了两个 data 字段的位移。 - Weather Vane
@weatherVane 好的,我只是为了理解而这么说。另外,地址应该是十六进制形式的。所以你的疑问是无效的。 - Astha Arora
@john Bollinger 在结构体中交换 data1 和 data2 的声明只会影响结构体对象 obj 的内存空间,对吗?当我使用 malloc 创建一个内存块时,它会创建一个大小等于结构体对象 rt 大小的内存块?然后在这个内存块中存储 data1 和 data2 的值。在第一个代码片段中,我首先存储了 data1,因此 data1 的地址空间较小,但在第二个代码片段中,首先存储 data2,那么它的地址应该小于 data1。 - Astha Arora
@AsthaArora,如果成员按照分配顺序在内存中排列,那么您如何能够随后确定哪个是哪个? - John Bollinger
@ John Bollinger 你节点成员的相对地址是结构体布局的函数这是否意味着我们在结构体中声明成员的顺序就是它们在malloc分配的内存中存储的顺序? - user4418808
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接