C++:进程结束,退出代码为 139(被信号 11 中断:SIGSEGV)

C++: Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

我用 C++ 中的列表进行了测试,并为它创建了一个最简单的 class。我删除了一些检查和其他方法以仅显示重点。

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:: classes 来代替。我尝试使用本机类型尽可能简单地做到这一点。

您的代码造成堆栈溢出,因为它递归地从前一个节点的析构函数中删除下一个节点。当你有一百万个元素时,这会导致一百万次递归。在大多数平台上,堆栈大小限制在 1-8MB 左右,即使每个函数调用仅使用 8 个字节的堆栈(通常会更多)也会导致一百万个元素溢出。

您应该 non-recursively 删除 CList 析构函数中的项目:

CList::~CList() {
    CItem* item = this->first;
    while (item) {
        CItem* temp = item;
        item = item->next;
        delete temp;
    }
}