Управление памятью QVector

У меня есть очень простая фиктивная программа

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

Решение

Вам нужно прочитать о правило трех.

Что происходит, когда вы делаете

nodes.append(LevenshteinDBNode(size));

Вы создаете временный LevenshteinDBNode объект, который затем скопированный, приводя к двум объектам с двумя указателями на одну и ту же память. Временный объект затем уничтожается, что вызывает ваш деструктор и удаляет выделенную вами память. Теперь у вас есть копия объекта с указателем на удаленную память.

Вам необходимо реализовать конструктор копирования который делает так называемую глубокую копию выделенной памяти.


У вас также есть гораздо более тонкая ошибка в вашем коде, потому что вы не инициализируете указатель в LevenshteinDBNode конструктор по умолчанию. Это означает, что если у вас есть экземпляр, созданный по умолчанию, указатель будет иметь неопределенное значение, в действительности он будет указывать на случайное местоположение. Это приведет к неопределенному поведению, если созданный по умолчанию экземпляр будет уничтожен при попытке delete этот случайный указатель. Вам нужно инициализировать указатель на nullptr в конструкторе по умолчанию.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]