C++ 链表由类组成,抛出异常0xC0000005

C++ 链表由类组成,抛出异常0xC0000005,c++,class,linked-list,C++,Class,Linked List,因此,我有一个自己的链表实现,它可以成功地保留整数,并在需要时使用重载的[]运算符调用它们,但当涉及到在我的链表中存储一个类时,我似乎无法适当地调用该类(使用相同的[]运算符)。 调用我的链接列表的函数和成员 #include <iostream> #include <assert.h> template<typename T> struct node { T data; node<T>* next; }; template&l

因此,我有一个自己的链表实现,它可以成功地保留整数,并在需要时使用重载的[]运算符调用它们,但当涉及到在我的链表中存储一个类时,我似乎无法适当地调用该类(使用相同的[]运算符)。 调用我的链接列表的函数和成员

#include <iostream>
#include <assert.h>

template<typename T>
struct node {
    T data;
    node<T>* next;
};

template<typename T>
class Vectem {
private:
    node<T>* head;
    node<T>* last;
    int lenght;
public:
    void insert(T value) {
        last->next = new node<T>;
        last = last->next;
        last->data = value;
        last->next = NULL;
        if (isEmpty()) {
            head = last;
        }
        lenght++;
    }
    node<T>* search(int indx) {
        node<T>* current;
        current = head;
        int count=0;
        while (current != NULL) {
            if (count == indx) {
                break;
            }
            current = current->next;
            count++;
        }
        return current;
    }
    T& operator [](int indx) {
        assert(indx >= lenght - 1);
        T result;
        result = search(indx)->data;
        return result;
    }
};
#包括
#包括
样板
结构节点{
T数据;
节点*下一步;
};
样板
类向量{
私人:
节点*头;
节点*最后;
内部长度;
公众:
无效插入(T值){
last->next=新节点;
最后一个=最后一个->下一个;
最后->数据=值;
last->next=NULL;
if(isEmpty()){
头=最后一个;
}
长度++;
}
节点*搜索(int indx){
节点*电流;
电流=水头;
整数计数=0;
while(当前!=NULL){
如果(计数=indx){
打破
}
当前=当前->下一步;
计数++;
}
回流;
}
T&operator[](int indx){
断言(indx>=长度-1);
T结果;
结果=搜索(indx)->数据;
返回结果;
}
};
这里是我试图存储的主要函数和类

#include <iostream>
#include <fstream>
#include <string>
#include "VectemLibrary.h"
class word {
public:
    std::string value;
    int count;
    word(std::string value, int count): value(value),count(count) {

    }
    word() {
        value = "NOT ASSIGNED";
        count = 0;
    }
    word(const word& w1) {
        value = w1.value;
        count = w1.count;
    }
    ~word() {
        std::cout << "Word Destroyed" << std::endl;
    }
};
int main()
{
    Vectem<word> wordContainer;
    word newWord("hello", 1);
    wordContainer.insert(newWord);
    std::cout << wordContainer[0].value;
    
}
#包括
#包括
#包括
#包括“VectemLibrary.h”
类词{
公众:
std::字符串值;
整数计数;
单词(std::string value,int count):值(value),计数(count){
}
单词(){
value=“未分配”;
计数=0;
}
单词(常量单词和w1){
值=w1.0值;
count=w1.count;
}
~word(){

std::cout您发布的代码也存在其他问题(例如,
isEmpty()
未声明或定义),但我将重点讨论您明确提到的问题

在您的运营商中:

T& operator [](int indx) {
    assert(indx >= lenght - 1);
    
    // You declare this variable on the stack
    T result;
    
    result = search(indx)->data;
    
    // And then you return this variable by reference; this is not okay
    return result;
}
正如我的代码评论中提到的(以及@Johnny Mopp在他对你的帖子的评论中提到的),你不应该(不能)返回在返回函数中声明并在堆栈上构造的变量的引用或指针。一旦函数调用结束,堆栈上的任何内容都将被销毁,因此任何返回的指针或对此类变量的引用都将是悬空引用;使用所述指针或引用将导致未定义的行为

因此,您不希望返回对堆栈分配变量的引用,如
result
;您希望返回对节点本身内数据的引用(由
insert()
在堆上分配),因为在函数返回后,它仍然是有效的引用:


返回搜索(indx)->数据;

您的代码有几个问题,但最重要的是您根本没有初始化
vetem
最后一个
长度
成员。地址
0xCCCC
处的访问冲突错误很好地表明正在访问未初始化的内存d、 由于某些编译器/设置使用
0xCC
字节填充未初始化内存,因此在您的情况下,
head
last
最初是
0xcccc

您需要将适当的构造函数添加到
Vectem
(以及析构函数、复制构造函数和复制赋值运算符),例如:

模板
类向量{
私人:
节点*头;
节点*最后;
内部长度;
公众:
Vectem():head(NULL)、last(NULL)、lenght(0){}
向量项(const-Vectem&src):头部(空)、最后一个(空)、长度(0)
{
//根据需要将src的数据复制到*此。。。
}
~Vectem()
{
//清理*根据需要进行此操作。。。
}
向量和运算符=(常量向量和rhs)
{
如果(&rhs!=此){
//清除*此,并根据需要将rhs的数据复制到*此。。。
}
归还*这个;
}
...
};
或者,在C++11及更高版本中,可以直接在成员声明中初始化成员(另外,请确保根据添加移动构造函数和移动赋值运算符),例如:

模板
类向量{
私人:
节点*head=nullptr;
node*last=nullptr;
整数长度=0;
公众:
Vectem()=默认值;
向量项(const向量项和src)
{
//根据需要将src的数据复制到*此。。。
}
Vectem(Vectem&&src):头部(src.head),最后(src.last),长度(src.lenght)
{
src.head=nullptr;
src.last=nullptr;
src.lenght=0;
}
~Vectem()
{
//清理*根据需要进行此操作。。。
}
向量和运算符=(常量向量和rhs)
{
如果(&rhs!=此){
//清除*此,并根据需要将rhs的数据复制到*此。。。
}
归还*这个;
}
向量项和运算符=(向量项和rhs)
{
//根据需要清除此项。。。
head=rhs.head;rhs.head=空PTR;
last=rhs.last;rhs.last=nullptr;
长度=rhs.lenght;rhs.lenght=0;
归还*这个;
}
...
};
这就是说,
insert()
也有问题,因为它在检查
last
是否实际指向有效节点之前取消了对
last
的引用。请尝试类似的操作:

void插入(T值){
node*n=新节点{值,NULL};
如果(!head)head=n;
如果(上次)上次->下一步=n;
last=n;
++长度;
}
或者:

void插入(T值){
节点**p=(上一个)&(上一个->下一个):&head;
*p=新节点{值,NULL};
last=*p;
++长度;
}

T result;…return result;
您正在返回对局部变量的引用。也可以在
insert()中尝试
返回搜索(indx)->data;
你有
last->next=new node;
。但是你第一次调用这个函数时,
last
的值是什么呢?事实上,我并没有发布整个库,以免浪费你的时间阅读所有的函数。我想如果我只显示我们正在使用的函数