当调用类解构函数时,std :: string会抛出错误[关闭]

问题描述 投票:-1回答:1

我是编码的新手,所以如果这个问题看起来很愚蠢,请原谅我。我正在编写自己的List类,以便更好地理解列表的结构,但我遇到了一个问题。我动态分配了我的列表,因为我添加了更多的项目,我的程序上的解构函数运行得很好。但是,当我使用std :: string进行测试时,我遇到了一个问题。在我的解构器被调用之后它会不断抛出异常(尽管(我很确定)我删除了我单独分配的内存,而不是他们的内存(读取访问冲突)。

我尝试过使用智能指针而不是在我的deconstuctor中删除分配的内存,但最终会遇到同样的问题。在线查看,我似乎只能找到“只用解构器删除”,并且“在解构器中没有异常处理”。这两者都不是我写的问题。

首先,解决这个问题的相关代码(在我看来)。

#include <string>
#include <iostream>
using std::cout;
using std::cin;
using std::string;

template <class type>
class List
{
    struct Node
    {
        type data;
        Node* next;
    };

public:

    List();

    ~List();

    void addToList(type var);
private:

    Node head;
    Node *last, *lastAcc;

    unsigned int length, prevPos;
};

template <class type>
List<type>::~List()
{
    Node *prevPtr;
    lastAcc = head.next;

    while (lastAcc->next) // While the next pointer leads to something
    {
        // Go to that something, and delete the item you were on

        prevPtr = lastAcc;
        lastAcc = lastAcc->next;
        delete prevPtr;
    }

    delete lastAcc;
}


template <class type>
void List<type>::addToList(type var)
{
    if (length)
    {
        last->next = new Node;
        last = last->next;
        last->data = var;
    }
    else
    {
        head.data = var;
    }

    lastAcc = last;
    prevPos = length++;
}

template <class type>
List<type>::List()
{
    head.next = 0;
    prevPos = 0;
    lastAcc = last = &head;
    length = 0;
}

int main()
{
    string boi[] = { "Today is a good day", "I had an apple", "It tasted delicious" };

    List<string> multiString;

    for (int i = 0; i < 3; i++)
    {
        multiString.addToList(boi[i]);
    }
    return 0;
}

我希望代码运行得很好,如果我犯了错误,我认为错误会显示在我的代码上。不在std :: string上。任何帮助将不胜感激。

[编辑]补充说明,[lastAcc]缩写为上次访问;这只是我实现的目的,使得通过列表更快,而不是每次都从0开始。 [prevPos]显示列表中[lastAcc]的位置。如果您需要查看更多我的代码或解释任何内容,请告诉我们!

c++ exception stdstring
1个回答
1
投票

你没有在addToList中初始化last-> next,所以你的析构函数中的迭代会从列表的末尾开始。正确的代码是:

void List<type>::addToList(type var)
{
    if (length)
    {
        last->next = new Node();
        last = last->next;
        last->data = var;
    }
    else
    {
        head.data = var;
    }

    lastAcc = last;
    prevPos = length++;
}

区别是new Node()而不是new Node。第一个值初始化POD类型,第二个值不是。

或者,如果为Node定义构造函数,则new Nodenew Node()将是等效的:

struct Node
{
    Node(): next( 0 ) {}
    type data;
    Node* next;
};

为了获得较小的效率增益,您可以将值移动到节点中以防止复制:

struct Node
{
    Node(): next( 0 ) {}
    Node(type && data): data( std::move( data ) ), next( 0 ) {}
    type data;
    Node* next;
};

template <typename T>
void addToList(T&& var)
{
    if (length)
    {
        last->next = new Node(std::move(var));
        last = last->next;
    }
    else
    {
        head.data = std::move(var);
    }

    lastAcc = last;
    prevPos = length++;
}
© www.soinside.com 2019 - 2024. All rights reserved.