我优化了链接列表析构函数,如下所示:
template <class T>
class LinkedList
{
/* snip */
T* pData;
LinkedList* pNext;
};
template <class T>
LinkedList<T>::~LinkedList()
{
delete pData;
delete pNext;
}
现在我有点担心它可能会给大型列表带来麻烦。这段代码会导致堆栈溢出吗?如果是这样,关于多大的名单?
答案 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,它不仅仅是这样做的)。