我有这个非常简单的虚拟程序
levenshteindb.h:
#ifndef LEVENSHTEINDB_H
#define LEVENSHTEINDB_H
#include <QVector>
#include "levenshteindbnode.h"
class LevenshteinDB
{
unsigned size;
QVector<LevenshteinDBNode> nodes;
void realloc_rows(unsigned node);
public:
LevenshteinDB();
~LevenshteinDB();
void add_word();
};
#endif // LEVENSHTEINDB_H
levenshteindb.cpp:
#include "levenshteindb.h"
#include <cstring>
#include <cstdio>
LevenshteinDB::LevenshteinDB()
{
size=15;
nodes.append(LevenshteinDBNode(size));
}
LevenshteinDB::~LevenshteinDB()
{
}
void LevenshteinDB::add_word()
{
nodes.append(LevenshteinDBNode(size));
}
void LevenshteinDB::realloc_rows(unsigned newsize)
{
for(unsigned i=0;i<nodes.size();i++)
nodes[i].realloc(newsize);
}
levenshteindbnode.h:
#ifndef LEVENSHTEINDBNODE_H
#define LEVENSHTEINDBNODE_H
struct LevenshteinDBNode
{
LevenshteinDBNode();
LevenshteinDBNode(unsigned size);
~LevenshteinDBNode();
unsigned *row;
void realloc(unsigned newsize);
};
#endif // LEVENSHTEINDBNODE_H
levenshteindbnode.cpp:
#include "levenshteindbnode.h"
LevenshteinDBNode::LevenshteinDBNode(){};
LevenshteinDBNode::LevenshteinDBNode(unsigned size)
{
row = new unsigned[size];
}
LevenshteinDBNode::~LevenshteinDBNode()
{
delete[] row;
}
void LevenshteinDBNode::realloc(unsigned newsize)
{
delete[] row;
row=new unsigned[newsize];
}
main.cpp:
#include "levenshteindb.h"
int main()
{
LevenshteinDB *trie = new LevenshteinDB();
trie->add_word();
trie->add_word();
trie->add_word();
delete trie;
}
崩溃,似乎有一个巨大的(相比程序本身分配的内存)内存泄漏,但我真的无法理解什么是错的..
我正在使用qt 5.2
答案 0 :(得分:3)
您需要阅读the rule of three。
当你做的时候发生了什么
nodes.append(LevenshteinDBNode(size));
你创建一个临时 LevenshteinDBNode
objectm然后复制,导致两个对象有两个指针指向同一个内存。然后销毁临时对象,这会导致您的析构函数被调用,并删除您已分配的内存。现在你有了一个对象的副本,带有指向已删除内存的指针。
您需要实现一个复制构造函数,它会对所分配的内存执行所谓的深层复制。
您的代码中还有一个更微妙的错误,因为您没有在LevenshteinDBNode
默认构造函数中初始化指针。这意味着如果你有一个默认构造的实例,指针将具有不确定的值,实际上它将指向一个随机位置。如果在尝试delete
此随机指针时破坏默认构造的实例,则会导致未定义的行为。您需要在默认构造函数中初始化指向nullptr
的指针。