为什么我不能在堆栈内存而不是堆上实现链表?

时间:2020-11-09 02:26:10

标签: c++ singly-linked-list

struct node{
  int data;
  node* next;
}

int main(){
  Node *head; head->data = 999;
  Node *new_node; new_node->data = 1; head->next = new_node;
  cout << (head->next)->data;
}

此代码无效。如果我使用分配,则可以。我尝试在Google上搜索,但没人问到这个。

我的代码基于对链表的理解。所以随便烤我吧。

2 个答案:

答案 0 :(得分:1)

创建时 Node*您正在创建节点指针而不是节点。这只是一个变量,它将保存一个内存地址,而该内存地址将保存一个节点。由于您没有分配任何内存,因此在使用->运算符时实际上并没有要使用的节点。基本上,它在您的代码中不起作用,因为您正试图取消引用未初始化的指针,然后修改尚未分配的内存。

关于为什么不能使用静态内存创建链表的总体问题,这是由于范围规则和堆栈上的自动内存管理所致。链接列表的思想是您根据节点的内存地址将它们链接在一起。如果在堆栈上创建每个节点,则这些节点在超出范围后将被删除,因此即使保留指向其内存地址的指针,也无法假定它们不会被其他内容覆盖。当然,只有当您没有将整个事情都保持在同一范围内,并且可能不是您想要的时,这种情况才会发生。

答案 1 :(得分:1)

正如@drescherjm在注释中建议的那样,您可以创建一个Node的静态数组并对其进行索引。这样做的好处是代码仅在分配功能上有所不同。对于动态分配,您将使用new Node创建一个节点,并使用&heap[++size];

创建一个静态数组。

请注意,如果数组是全局数组,则它实际上不在堆栈上-它必须是局部变量才能在堆栈上。

#include <iostream>

struct Node
{
    long data;
    Node *next;
};

Node heap[1000];
int capacity = 1000;
int size = 0;

Node *alloc()
{
    // For dynamic allocation you would:
    // return new Node;
    
    // For stack allocation you would:
    // return &heap[++size];

    if (size >= capacity)
        throw std::bad_alloc();
    return &heap[size++];
}

int main()
{
    Node *head = alloc();
    head->data = 999;
    std::cout << "head: " << head << " (value: " << head->data << ")\n";

    Node *new_node = alloc();
    new_node->data = 1;
    head->next = new_node;
    std::cout << "node: " << new_node << " (value: " << (head->next)->data << ")\n";

    std::cout << "heap: " << heap << " (used/capacity: " << size << "/" << capacity << ")\n";

    return 0;
}

https://onlinegdb.com/r1g-w4LKw上尝试