在此代码导致故障之前,有多大可以调用堆栈?

时间:2013-08-21 10:55:08

标签: c++ linked-list stack-overflow

我优化了链接列表析构函数,如下所示:

template <class T>
class LinkedList
{
    /* snip */
    T* pData;
    LinkedList* pNext;
};

template <class T>
LinkedList<T>::~LinkedList()
{
    delete pData;
    delete pNext;
}

现在我有点担心它可能会给大型列表带来麻烦。这段代码会导致堆栈溢出吗?如果是这样,关于多大的名单?

1 个答案:

答案 0 :(得分:3)

堆栈的大小由许多因素决定,例如系统上的OS /编译器/配置设置。

我肯定不会使用递归方法来删除列表中的元素,因为你可能会溢出堆栈 - 你可以通过创建一个包含X元素的列表来尝试这个,如果可行的话,加倍X,直到你达到堆栈溢出 - 我几乎可以保证它发生在几千个元素内(可能是10-100k,但肯定不会多于此)。

用于删除二叉树等的递归函数更容易被接受,因为(假设合理的平衡)递归级别的数量是log2(n),而不是n,所以你可以拥有大量的堆栈溢出之前的元素。

我上了你的课,并将其扩展到了#34; work&#34; (这可能与您使用它的方式完全不同,但它可以解释问题):

#include <iostream>

using namespace std;

template <class T>
class LinkedList
{
public:
    LinkedList() : pNext(0), pData(0) {};
    LinkedList(T e) : pNext(0) { pData = new T(e); }
    LinkedList(LinkedList* l, T e) : LinkedList(e) { pNext = l;}

    LinkedList *AppendFirst(LinkedList *l) { l->pNext = this ; return l; }

    LinkedList *Next() { return pNext; }

    T Data() { return *pData; }

    ~LinkedList();
private:
    T* pData;
    LinkedList* pNext;
};

#if 0
template <class T>
LinkedList<T>::~LinkedList()
{
    delete pData;
    delete pNext;
};
#else
template <class T>
LinkedList<T>::~LinkedList()
{
    LinkedList<T>* p;
    LinkedList<T>* q;
    p = pNext;
    while(p)
    {
        q = p->pNext;   // Save next link. 
        p->pNext = NULL;   // Break the link. 
        delete p->pData;
        p->pData = NULL;
        delete p;
        p = q;
    }

    delete pData;
};
#endif


typedef LinkedList<int> IntList;

int main()
{
    for(int x = 0; x < 30; x++)
    {
        cout << "Trying " << (1 << x) << " elements" << endl;
        IntList *head = new IntList(-1);
        for(int i = 0; i < (1 << x); i++)
        {
            head = head->AppendFirst(new IntList(i));
        }
        cout << "Now destroying " << (1 << x) << " elements" << endl;
        delete head;
    }
}

如果我将#if 0更改为#if 1(或具有该效果的其他内容),则适用于128K元素并在256K时崩溃。如果我在#else中使用迭代方法,我必须在它到达268435456(256M条目)时停止它,因为我的机器没有足够的内存,并且开始交换错误(我只有16GB的RAM,它不仅仅是这样做的)。