【问题标题】:Malloc memory layoutmalloc 内存布局
【发布时间】:2015-06-22 16:51:17
【问题描述】:

您好,我有以下代码来创建链表

#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 as 1000 的内存地址,那么我将得到next_node-&gt;data1 is 1000 的内存地址和next_node-&gt;data2 is 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 is 2000 的地址那么我得到next_node-&gt;data1 as 2004 和data2 is 2008 但shouldn't it be the other way as we are first storing the data2 in the memory location using the next_node pointer ? 的内存地址

【问题讨论】:

  • 我怀疑它会有所不同。在代码块 2 中,您正在打印 data2 的地址,然后是 data1。同样在代码块 2 中,如果 next_node 为空块,您不会打印 next_node 的地址。你能运行程序并在两种情况下显示程序输出的确切结果吗?
  • 在使用 printf() 函数时,(通常)最好以 '\n' 结束格式字符串,因为这会导致输出刷新到标准输出。当前格式字符串中的前导 '\n' 会导致显示先前的 printf(),而不是当前的 printf()。
  • 函数:append()有这一行:'printf("\n第一个元素添加成功");'但是,如果 malloc 失败,那么这个 printf() 仍然会被执行,但是节点没有被添加
  • 函数:append() 在第一个节点之后添加时,如果malloc失败,则代码继续,就像malloc成功一样。
  • 我认为你应该退后一步,考虑一下cmets和答案,而不是试图反驳它们。

标签: c pointers data-structures malloc


【解决方案1】:

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

【讨论】:

  • 我认为这个问题还是有一些不一致的地方,因为在第一个例子中地址是1000和1000和1004,但在第二个例子中是2000和2004 和 2008。 2000 的额外字段从哪里取代了两个 data 字段?
  • @weatherVane 好吧,我只是出于理解的目的,地址也是十六进制形式。所以你的怀疑是无效的
  • @john Bollinger 交换结构中data1和data2的声明只会影响结构对象obj rt的内存空间?当我使用 malloc 创建一个内存块时,它创建了一个大小等于结构对象 rt 大小的内存块?然后在这个内存块中,我存储 data1 和 data2 的值。在第一个 sn-p 中,我首先存储了 data1,因此 data1 的地址空间小于 data2,但在第二个中,首先存储了 data2,然后它的地址应该小于 data1。
  • malloc 分配的内存空间中的地址是否应该取决于我们在该内存空间中存储值的顺序。使用 malloc 时,我们只是创建了一块大小等于 stryct 对象大小的内存
  • @AsthaArora,不,存储特定成员的位置从不与您执行任务的顺序相关。 struct 声明本质上是成员如何在内存中布局的映射。结构是动态分配的这一事实几乎与此无关。
猜你喜欢
  • 1970-01-01
  • 2012-08-28
  • 2019-08-21
  • 1970-01-01
  • 2016-09-11
  • 2012-07-18
  • 2011-03-10
  • 2010-12-15
  • 2013-10-13
相关资源
最近更新 更多