C++中的内存分配的问题

C++中类和结构体的对象声明有两种方式:

  1. 直接声明的方式:
Node nodes;

这种方式声明的变量nodes是创建在栈区的。由系统自动回收。

  1. 使用new的方式:
Node *nodes=new Node;

这种方式是创建在堆区的,是要程序员自己申请管理,系统不会自动回收。需要使用delete回收。

下面看一段程序:

int main()
{
    //create Linklist
    Node nodes;
    Node* node=&nodes;
    nodes.val=0;
    for(int i=1;i<5;i++)
    {
        Node nodei;
        nodei.val=i;
        node->next=&nodei;
        node=node->next;
    }
    node->next=NULL;

    printf("link list:\n");
    Node* cur=&nodes;
    while(cur!=NULL){
        printfn
        cur=cur->next;
    }

}

上面这段程序的本意是要创建一个链表,0,1,2,3,4;但是最后的显示结果是:0,4

通过单步调试,查看变量地址信息,发现在进入循环后使用上述第一种方式创建的Node变量每一次的地址都是相同的。

(gdb) p &nodei
$2 = (Node *) 0x7fffffffde50

(gdb) p &nodei
$3 = (Node *) 0x7fffffffde50
(gdb) c
Continuing.

Breakpoint 1, main () at getPenultimate_KNode.cpp:107
107         nodei.val=i;
(gdb) p &nodei
$4 = (Node *) 0x7fffffffde50

(gdb) p &nodei
$3 = (Node *) 0x7fffffffde50
(gdb) c
Continuing.

Breakpoint 1, main () at getPenultimate_KNode.cpp:107
107         nodei.val=i;
(gdb) p &nodei
$4 = (Node *) 0x7fffffffde50

本以为是应该每次申请一个新的变量的地址都不同的,但是事实告诉我们是相同的地址。猜测应该是变量名称相同,然后地址分配成了相同的地址。为了验证一些,做了如下测试:

int main()
{
    //create linklist
    Node node0;
    Node* node=&node0;
    node0.val=0;

    Node node1;
    node1.val=1;
    node->next=&node1;
    node=node->next;

    Node node2;
    node2.val=2;
    node->next=&node2;
    node=node->next;
    node->next=NULL;


    printf("link list:\n");
    Node* cur=&node0;
    while(cur!=NULL){
        printf("%i\n",cur->val);
        cur=cur->next;
    }
}

这一次的结果正确了,因为不同的变量名称分配到了不同的地址,不会出现变量地址覆盖的问题。

或者使用new的方式来申请新的Node,这样每次申请的都是新的内存地址。

void LinkList::create(){
    int temp;
    cin>>temp;
    Node* p=head;

    while(temp!=-1){
        Node *newNode=new Node;
        newNode->val=temp;
        newNode->next=NULL;

        //connect to link list
        p->next=newNode;
        p=p->next;
        //otherwise, it will in a infinite loop
        cin>>temp;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值