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

时间:2020-10-13 06:40:14

标签: c++ segmentation-fault

我用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::类。我试图使用本机类型做到这一点,尽可能简单。

1 个答案:

答案 0 :(得分:0)

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

您应该以非递归方式删除CList析构函数中的项目:

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