动态内存和链表

Dyamic memory & Linked Lists

本文关键字:链表 内存 动态      更新时间:2023-10-16

好的,所以假设我们在C 中有一个链接的列表实现。此外,假设节点是一个类,列表本身是类,看起来像这样:

#include <iostream>
using namespace std;
class List;
class Node
{
private:
    Node(char, Node*);
    char data;
    Node* next;
    friend class List;
    friend ostream& operator<<(ostream&, const List&);
};
class List
{
public:
    List(int = 0);
    List(const List&);
    ~List();
    bool gotoBeginning();
    bool gotoEnd();
    bool gotoNext();
    bool gotoPrior();
    bool insert(char);
    bool remove(char&);
    bool empty() const;
    bool full() const;
    bool clear();
    List& operator=(const List&);
    friend ostream& operator<<(ostream&, const List&);
private:
    Node* head;
    Node* cursor;
};
#endif

假设列表为空。此外,假设我们只是将一个新元素" z"插入列表中,这意味着该列表当前具有1个节点。

让我们看一下插入功能:

bool List::insert(char item)
{
    if(empty())
    {
        Node* newNode = new Node(item, NULL);
        head = cursor = newNode;
        return true;
    }
    else
    {
        // I dont need to show this part because the above code will suffice
    }
}

好吧,所以我们都知道,为节点指针的变量newNode分配了存储位置,其中包含存储在堆上的节点。

现在记住,我们刚刚创建了一个新节点,letts假设传递到插入函数的项目为'z'

    内存分配堆栈堆    ||    ||    |/ |/ 512 902内存地址|----- || ---> | ----- | ----- ||902 |||'z'|null || ------- | --- || ----- | ----- |newnode(无名称/newNode)变量名称

(没有名称):因为在堆上分配的内存以外,不能直接访问指针。

我遇到的问题就是这样。NewNode指针是否在堆栈上创建,并在上面显示的某些内存地址(如512)进行了评估?还是指针从未分配在堆栈上(因此只需删除上面的512),而仅指向内存的内存(902)?

我要问的原因是因为插入功能内部IF语句内部的第二行代码将newNode分配给Head和Cursor

那让我感到困惑。头部和光标现在是否包含地址512或902?

另外,如果我们要继续并在插入功能内部的其他语句内部写入代码,则看起来像这样:

bool List::insert(char item)
{
    if(empty())
    {
        Node* newNode = new Node(item, NULL);
        head = cursor = newNode;
        return true;
    }
    else
    {
        Node* newNode = new Node(item, NULL);
        cursor = cursor->next = newNode; // what is this line doing
        return true;
    }
    return false;
}

因此,cursor->next如何获得新节点的值,而cursor也获得了新节点的值。

是的,上面的功能正常,我在项目上有一个A,因此所有代码都是正确的,但是我提到的概念正在困扰我

new返回的指针需要存储在某个地方,并且存储在堆栈变量的newNode中。newNode的值(其内容)是new返回的地址。

当您将指针分配给另一个指针时,它是指针的值,内容,地址指向指向的地址。

所以当您这样做时

head = newNode;

然后head将获得与newNode相同的值,并指向由new表达式分配的内存。


让我们以一个小例子:说你有两个指示:

int* a;
int* b;

您分配一些内存并分配给a

a = new int;

现在,内存看起来像这样:

 ----  -------------------------- |A | -> |分配的内存| ----  -------------------------- 

然后您从a分配到b

b = a;

然后记忆看起来像这样:

 --- |A | - 。  ---  | -----------------------        >  -> |分配的内存|  ---  | ----------------------- |b | - ' --- 

确切的变量ab存储在哪里并不重要,它们指向的位置也不重要。

cursor = cursor->next = newNode; // what is this line doing

请注意,分配不会同时进行。它从右到左传播。这是一个更详细的代码,它与上面的行相同:

Node* oldNode = cursor;
cursor = newNode;
oldNode->next = newNode;

在某些情况下(任务超载运算符)以该顺序写下来可能是有益的。