C++模板类调用析构函数时发生异常
黄舟
黄舟 2017-04-17 13:16:07
0
3
640

我是大二的学生,在做数据结构课设。用模板类写了一个List的数据结构,存放的数据是一个自定义的class。现在的问题在于每次调用析构函数的时候都会发生异常。根据追踪,是在调用传入的自定义类的析构函数时候出现了内存无法访问的错误。
自定义类的定义如下:

class passenger
{
public:
    passenger();
    passenger(string ID, string name, int totalMileage);
    passenger(const passenger& p);
    ~passenger() {};
    void show();
    
private:
    string ID;
    string name;
    int totalMileage;
};

ListNode定义如下:

#define ListNodePosi(T) ListNode<T>*
template <typename T>struct ListNode
{
    // 成员
    T data;// 数值
    ListNodePosi(T) pred;// 前驱
    ListNodePosi(T) succ;// 后继

    // 构造函数
    ListNode() {}
    ListNode(T e, ListNodePosi(T) p = NULL,ListNodePosi(T) s = NULL)
        : data(e), pred(p), succ(s) {}
    ~ListNode() 
    {}

    // 操作接口
    ListNodePosi(T) insertAsPred(T const& e);
    ListNodePosi(T) insertAsSucc(T const& e);
};

List的析构函数会调用自己编写的remove函数,追踪时发现是remove这里出了问题。

template<typename T>// 此处传入我自定义的类
T List<T>::remove(ListNodePosi(T) p)
{
    T e = p->data;
    p->pred->succ = p->succ;
    p->succ->pred = p->pred;
    delete[] p;
    _size--;
    return e;
}

在进行delete[] p;这条语句时出现错误,继续追踪,发现是在调用自定义类的析构函数时出现了问题,提示内存无法访问。
异常的提示为:

引发了异常: 读取访问权限冲突。
std::_String_alloc<std::_String_base_types<char,std::allocator<char> >
::_Myres(...) 返回 0x77E0EB64。

但是我的自定义类中并没有用new申请新的空间,为什么会出现这样的问题?
从网上查到资料说是深拷贝浅拷贝一块的问题,于是我提供了一个复制构造函数,但是问题依旧,请问该如何解决?
谢谢!

因为我的数据是通过二进制文件读入的,经过排查之后发现是读文件之后再调用析构函数会出现这样的问题。
下面是我的读文件的代码:

template<typename T>
void List<T>::createList(ifstream &file)
{
    T e;
    while (file.read(reinterpret_cast<char *>(&e), sizeof(T)))
    {
        insertAsLast(e);
    }
}

相关函数代码(List文件中):

template<typename T>
ListNodePosi(T) List<T>::insertAsLast(T const& e)
{
    _size++;
    return trailer->insertAsPred(e);
}

另一个相关函数(ListNode中):

template<typename T>
ListNodePosi(T) ListNode<T>::insertAsPred(T const & e)

    {
        ListNodePosi(T) x = new ListNode(e, pred, this);
        pred->succ = x;
        pred = x;
        return x;
    }

main函数中进行了一下测试

ifstream rpassfile("passenger.dat", ios_base::in | ios_base::binary);
List<passenger> p2;
p2.createList(rpassfile);
p2.traverseShow();
rpassfile.close();

基本可以确定问题就出在这个部分。读完文件之后,对于读文件时创建的列表无法调用析构函数。

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

reply all(3)
大家讲道理

Deleting the memory of a single T type element should not require square brackets. Square brackets are only used when deleting an array

黄舟

You read the file and build a linked list using
reinterpret_cast<char *>(&e), sizeof(T))
But depending on the implementation of string, it will cause the size of your passenger class instance to be inconsistent, so all The data coming in is all messed up

刘奇

Please check whether the same pointer has been deleted twice, or a pointer that has not allocated memory has been deleted;

Unfamiliarity with deep and shallow copying will indeed cause this result, so please focus on checking whether there are two pointers pointing to the same memory space, especially the local objects within the function. The destructor of the local object will be automatically called at the end of the function execution. , if there is a pointer to a local object pointing to the space outside the function, this part of the space will be released, and it is illegal to access or release it again.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template