【C++】内存动态分配问题记录

遇到的问题

刷题的时候,遇到关于链表的操作,忘记给节点分配空间,导致错误。由于指针的使用频率较低,思考良久,秉着实践是检验真理的唯一标准的思想,整理一下关于内存动态分配的问题。

思考

因为链表中每一个节点都是一个指针,如果没有给每一个指针(节点)都申请空间的话,会导致每个指针(节点)都是一样的地址,则会导致错误。

实践

首先看如果没有申请内存空间会导致的错误:
#include <iostream>
#include <stdlib.h>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

int main() {
    ListNode *l3 = new ListNode(0);
    ListNode *head3 = l3;
    for(int i = 1; i < 10; ++i) {
        ListNode tmp(i);
        l3->next = &tmp;
        l3 = &tmp;
        cout << l3 << " " << l3->val << " " << "\n";
    }
    cout << "l3 : ";
    while(head3 != NULL && n != 0) {
        cout << head3 << " " << head3->val << "\n";
        head3 = head3->next;
        n--;
    }
    return 0;
}

我们的初衷是想创建九个节点并且给每个节点赋值。
但是输出结果为:

0x7ffc4cc26850 1 
0x7ffc4cc26850 2 
0x7ffc4cc26850 3 
0x7ffc4cc26850 4 
0x7ffc4cc26850 5 
0x7ffc4cc26850 6 
0x7ffc4cc26850 7 
0x7ffc4cc26850 8 
0x7ffc4cc26850 9 
l3 : 0x1dd1070 0
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9
0x7ffc4cc26850 9

除了head3节点是正确的,后面赋值的节点以及节点指向的下一个节点地址都是一样的,说明在循环中,尽管节点指向的值每次会改变之外,定义的节点tmp并没有申请新的内存来存储。就会导致这个链表错误。

正确姿势
#include <iostream>
#include <stdlib.h>

using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

int main() {
    ListNode *l1 = new ListNode(0);
    ListNode *l2 = new ListNode(0);
    ListNode *head1 = l1;
    ListNode *head2 = l2;
    for(int i = 1; i < 10; ++i) {
        ListNode *tmp = new ListNode(i);
        l1->next = tmp;
        l1 = tmp;
        cout << l1 << " " << l1->val << " " << "\n";
        //delete(tmp);
    }
    cout << endl;
    for(int i = 1; i < 10; ++i) {
        ListNode *tmp = (ListNode *)malloc(sizeof(ListNode));
        tmp->val = i; tmp->next = NULL;
        l2->next = tmp;
        l2 = tmp;
        cout << l2 << " " << l2->val << " " << "\n";
        //free(tmp);
    }
    cout << endl;
    cout << "l1 : ";
    int n = 20;
    while(head1 != NULL && n != 0) {
        cout << head1 << " " << head1->val << "\n";
        head1 = head1->next;
        n--;
    }
    cout << endl;
    cout << "l2 : ";
    while(head2 != NULL && n != 20) {
        cout << head2 << " " << head2->val << "\n";
        head2 = head2->next;
        n++;
    }
    return 0;
}

使用new或者malloc(需要添加头文件<stdlib.h>),但是在申请之后千万不要用delete或者free释放空间,因为这里需要的就是分配空间,如果需要释放,则需要在链表中操作。

输出地址显真相

在输出地址的时候发现

    cout << l1 << " " << l2 << " " << l3 << " " << head1 << " "<< head2 << " "<< head3 << endl;
	cout << l1->next << " " << l2->next << " " << l3->next << " " << head1->next << " "<< head2->next << " "<< head3->next << endl;

最开始的输出为:

//输出为
0x1dd1030 0x1dd1050 0x1dd1070 0x1dd1030 0x1dd1050 0x1dd1070
0 0 0 0 0 0

每次申请的指针都会递增20个字节,然后就会发现,结构体中int占4个字节,ListNode占16个字节。并且在后面动态的分配内存的时候也会发现依次递增20个字节。
在给三个链表进行赋值操作之后输出为:

//输出为
0x1dd1190 0x1dd12b0 0x7ffc4cc26850 0x1dd1030 0x1dd1050 0x1dd1070
0 0 0x7ffc4cc26850 0x1dd1090 0x1dd11b0 0x7ffc4cc26850

通过这个也能发现,如果没有分配内存,会导致链表出现bug~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值