是否可以在C ++中的堆栈上创建链接列表?

时间:2009-10-12 20:06:18

标签: c++ linked-list stack

几周前我刚开始学习C ++。所以现在我有这个学校作业问题,要求我实现链接列表而不使用“新”或任何与动态分配内存有关(并且不能使用STL中的任何ADT)。教授说一切都可以在堆栈上完成,但是如何?我从星期五开始就一直在努力,但仍然没有运气。

它说:保持一堆文件名被读取。对堆栈使用以下数据结构:

struct Node { 
string fileName; 
Node *link; 
}; 

我试图避免使用new,但是当我将列表的头部传递给递归方法调用时,它总是给我“分段错误”或“BUS错误”。关于我如何解决这个问题的任何想法?

10 个答案:

答案 0 :(得分:10)

堆和堆栈之间的区别主要是(不仅是,但主要是为了这个问题)分配内存的方式以及如何释放内存。如果要在堆上分配节点,则说new Node,系统将为您提供内存,跟踪使用哪些块以及哪些块是空闲的,并为您提供释放的方法。一旦你不再需要它就会大块。

但是你也可以在堆栈中的数组中拥有一个节点池。 (自动变量是堆栈变量。)您可以从该池“分配”,跟踪阵列中的哪些节点以及哪些节点是空闲的,并将未使用的节点标记为不再需要它们的免费节点。但是,由于数组的大小在编译时是固定的,这意味着您的列表具有最大长度。

答案 1 :(得分:7)

我创建了一个你可能会觉得很有启发性的小样本。我在堆栈上创建了一个单独链接的元素列表。注意如何反向创建列表以及如何使用递归来“分配”所需的itmes数量。还要注意列表如何作为参数传递给参数。希望这有帮助,祝你好运。

#include <cstdio>

using namespace std;

struct Node {
    Node* next_;
    int value_;
};

// Creates a linked list of nodes containing raising values.
void intList(Node* prevNode, int restValue) {
    if (restValue) {
       // A node on the stack, which is linked to list created so far.
       Node node;
       node.next_ = prevNode;
       node.value_ = restValue; 
       // Create a next node or print this list if rest runs to zero.
       intList(&node, rest - 1);
    }
    else {
    // Depest recursion level, whole list is complete.
    for (Node* iter = prev; iter; iter = iter->next_)
        printf("item %d\n", iter->value_);
    }
}

int main() {
    intList(NULL, 10);
}

答案 2 :(得分:2)

调用函数后,该函数的堆栈分配是固定的。

分配更多堆栈内存的唯一方法是调用另一个函数。然后可以调用另一个函数。然后可以调用另一个函数。或者也许它们都可以是相同的功能......

每个函数调用都有自己的固定大小的堆栈,但函数调用图本身就是这些堆栈的可变大小堆栈。

答案 3 :(得分:2)

你可能应该和你的教授谈谈并澄清要求,因为根据你的描述,对于一个新的c ++程序员来说,这似乎是一个非常奇怪的任务。要求只在堆栈上实现具有内存的链表是至关重要的。

答案 4 :(得分:1)

想想数组。如果需要,可能不止一个。

答案 5 :(得分:1)

没有太多信息:

递归实现是否需要?进行递归调用时,会得到一个新堆栈。 也许你可以使用迭代方法。

答案 6 :(得分:1)

使用alloca()而不是malloc()函数在调用函数的堆栈帧上动态分配内存而不是堆。您不必担心释放内存,因为它会在函数返回时自动释放。

link text

答案 7 :(得分:0)

如果您知道需要存储多少个文件名,可以使用struct Node数组并从中构建列表。

使用迭代一个可能的替代方法是在函数中有一个结构Node对象,并在递归调用中将指针传递给它,在那里你使用指针作为该函数堆栈框架中Node对象的下一个链接。

请注意,在后一种情况下,列表仅在最深的递归时有效,当递归调用返回其调用者时,列表会再次被分解。

答案 8 :(得分:0)

要“在堆栈上创建链接列表”,通常使用像alloca这样的函数来获取更多的堆栈内存。然而,这听起来并不像你被要求做的那样。

听起来你应该在堆栈上保留堆栈,而不是任意链接列表。作为提示,您要执行的操作的一般语法:

void push(struct Node *oldHead, String elem) {
    struct Node newHead;
    head.fileName = elem;
    head.next = oldHead.
    struct Node *head = &newHead
    // then you need to continue what you're doing in this function, since
    // returning will effectively pop the stack.

有一些(非平凡的)技术可以沿着这些方式实现完整的垃圾收集列表,但这超出了你正在做的范围。

答案 9 :(得分:0)

可以使用C ++ address-of operator (&amp;)来检索指向堆栈上对象的指针,而不是使用 new 动态分配内存。 / p>

由于以这种方式生成链表是有问题的,除了作为家庭作业,我不确定这是否是实际需要的。如果没有代码示例,很难确切地说出问题所在。