我用C ++中的列表进行了测试,并为此创建了一个最简单的类。我删除了一些检查和其他方法以仅显示要点。
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.00)
PROJECT(test)
SET(CMAKE_CXX_STANDARD 98)
ADD_EXECUTABLE(test main.cpp CList.h)
CList.h
#ifndef CLIST_H
#define CLIST_H
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <stdint.h>
struct CItem {
size_t data;
CItem *prev;
CItem *next;
CItem(size_t item);
~CItem();
};
CItem::CItem(size_t item) {
this->data = item;
this->prev = NULL;
this->next = NULL;
}
CItem::~CItem() {
delete this->next;
}
class CList {
CItem *first;
CItem *last;
size_t length;
public:
CList();
~CList();
CList &add(size_t data);
};
CList::CList() {
this->first = NULL;
this->last = NULL;
this->length = 0;
}
CList::~CList() {
delete this->first;
}
CList &CList::add(size_t data) {
CItem *item = new CItem(data);
if (!item) {
fputs("Not enough memory", stderr);
exit(1);
}
if (!this->length) {
this->first = this->last = item;
} else {
item->prev = this->last;
this->last->next = item;
this->last = this->last->next;
}
this->length++;
return *this;
}
#endif //CLIST_H
main.cpp
#include "CList.h"
int main() {
CList list;
for (size_t i = 0; i < 1000000; i++) {
list.add(i);
}
return 0;
}
如您所见,CList析构函数调用第一个项目的CItem析构函数,后者递归调用其他项析构函数。
为了测试代码,我在列表中添加了1,000,000个项目。代码应该释放内存。但是我在CItem析构函数上得到了SIGSEGV错误(不是在第一项上)。 当我仅添加100,000个项目时,没有错误。错误出现,并包含大量元素。
同样,那不是一个真正的代码,只是一些测试。我知道我可以至少使用std::
类。我试图使用本机类型做到这一点,尽可能简单。
答案 0 :(得分:0)
您的代码会导致堆栈溢出,因为它从前一个的析构函数中递归地删除了下一个节点。当您拥有一百万个元素时,这将导致一百万次递归。在大多数平台上,堆栈大小限制为1-8MB左右,即使每个函数调用仅使用8个字节的堆栈(通常会更多),也会导致上百万个元素溢出。
您应该以非递归方式删除CList
析构函数中的项目:
CList::~CList() {
CItem* item = this->first;
while (item) {
CItem* temp = item;
item = item->next;
delete temp;
}
}