我应该如何在C++中为此类编写destructor?
我有一个具有这种结构的课程:
class myClass(){
public:
myClass(){//empty constructor}
void insertRecursively(string word) {
myClass* node = this;
for (int i = 0; i < word.length(); i++) {
if (node->map.find(word.at(i)) == node->map.end()) {
node->map[word.at(i)] = new myClass();
}
node = node->map[word.at(i)];
}
node->isEnd = true;
}
private:
unordered_map<char, myClass*> map = {};
bool isEnd = false;
}
我尝试以这种方式编写destructor,但它给我错误的“ std :: bad_alloc':
~myClass() {
clear(map);
}
void clear(unordered_map<char, myClass*> map) {
for (auto& pair : map) {
if (pair.second != nullptr) {
clear(pair.second->map);
}
delete pair.second;
}
}
从我到目前为止所知道的,我使用新关键字在堆上分配了内存,所以我应该应该为myclass创建驱动器。我需要递归地这样做,因为地图包含其他myllass指针的指针。
我已经研究了几个小时,但仍然无法弄清楚。 谁能帮助我发现会导致“ std :: bad_alloc”的问题?
我的整个代码:
class Trie {
public:
Trie() {
}
void insert(string word) {
Trie* node = this;
for (int i = 0; i < word.length(); i++) {
if (node->map.find(word.at(i)) == node->map.end()) {
node->map[word.at(i)] = new Trie();
}
node = node->map[word.at(i)];
}
node->isEnd = true;
}
bool search(string word) {
Trie* node = this;
for (int i = 0; i < word.length(); i++) {
if (node->map.find(word.at(i)) == node->map.end()) {
return false;
} else {
node = node->map[word.at(i)];
}
}
return node->isEnd;
}
bool startsWith(string prefix) {
Trie* node = this;
for (int i = 0; i < prefix.length(); i++) {
if (node->map.find(prefix.at(i)) == node->map.end()) {
return false;
} else {
node = node->map[prefix.at(i)];
}
}
return true;
}
~Trie() {
clear(map);
}
void clear(unordered_map<char, Trie*> map) {
for (auto& pair : map) {
if (pair.second != nullptr) {
clear(pair.second->map);
}
delete pair.second;
}
}
private:
unordered_map<char, Trie*> map = {};
bool isEnd = false;
};
I have a class that has this kind of structure:
class myClass(){
public:
myClass(){//empty constructor}
void insertRecursively(string word) {
myClass* node = this;
for (int i = 0; i < word.length(); i++) {
if (node->map.find(word.at(i)) == node->map.end()) {
node->map[word.at(i)] = new myClass();
}
node = node->map[word.at(i)];
}
node->isEnd = true;
}
private:
unordered_map<char, myClass*> map = {};
bool isEnd = false;
}
I tried write destructor in this way but it gives me error 'std::bad_alloc':
~myClass() {
clear(map);
}
void clear(unordered_map<char, myClass*> map) {
for (auto& pair : map) {
if (pair.second != nullptr) {
clear(pair.second->map);
}
delete pair.second;
}
}
From what I known so far, I allocated memory on heap by using new keyword, so I should create destructor for myClass. I need to do this recursively because map contains pointers to other myClass pointers.
I've researched several hours and still cannot figure it out.
Can anyone help me to spot the problem that will cause 'std::bad_alloc' ?
My entire code:
class Trie {
public:
Trie() {
}
void insert(string word) {
Trie* node = this;
for (int i = 0; i < word.length(); i++) {
if (node->map.find(word.at(i)) == node->map.end()) {
node->map[word.at(i)] = new Trie();
}
node = node->map[word.at(i)];
}
node->isEnd = true;
}
bool search(string word) {
Trie* node = this;
for (int i = 0; i < word.length(); i++) {
if (node->map.find(word.at(i)) == node->map.end()) {
return false;
} else {
node = node->map[word.at(i)];
}
}
return node->isEnd;
}
bool startsWith(string prefix) {
Trie* node = this;
for (int i = 0; i < prefix.length(); i++) {
if (node->map.find(prefix.at(i)) == node->map.end()) {
return false;
} else {
node = node->map[prefix.at(i)];
}
}
return true;
}
~Trie() {
clear(map);
}
void clear(unordered_map<char, Trie*> map) {
for (auto& pair : map) {
if (pair.second != nullptr) {
clear(pair.second->map);
}
delete pair.second;
}
}
private:
unordered_map<char, Trie*> map = {};
bool isEnd = false;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我将注意力集中在以下代码上。
修剪几个字符...
观察到您在char和myclass*上声明了本地项目地图,但是您将clear()宣布为在char和myclass上的地图上操作,而不是通过char和myclass*的地图。
*有所作为。
I draw your attention to the following lines of code.
Trimming a few characters...
Observe that you declared the local item map over char and myClass*, but you declared clear() as operating on a map over char and myClass, as opposed to a map over char and myClass*.
The * makes a difference.
您要么开始使用 Smart Pointer ,要么需要提出一个用
myClass
实例创建的new
的概念。后者可能是:
由myClass
的AmyClass
的另一个实例所有(让我们称其为ander> lands
)其中&amp; a
出现在所有者.map
中(您已经在执行此操作)。所有者
被销毁时,它必须(直接)释放所有实例:Either you start to use smart pointers or you need to bring up a concept of ownership for your
myClass
instances created withnew
.The latter could be:
a
ofmyClass
are owned by another instance ofmyClass
(lets call itowner
) where&a
appears inowner.map
(You are doing this already).owner
becomes destroyed, it has to free all instances it (directly) owns:您的
trie :: clear()
方法两次删除相同的trie
。destructor
〜trie
调用clear(pair.second-&gt; map)
,然后调用delete pair.second.second
,与clear(pair.second-&gt; map)由于
delete
调用指向at数据的删除器。在同一地图上两次呼叫clear()
两次意味着第二个调用试图删除已删除的数据,这会导致崩溃。调用delete
在指针上不会更改指针的值,这就是为什么nullptr
检查检查什么都不做。由于destructor调用
clear()
,因此clear()
方法无需清楚地递归地调用自己。只需删除地图指针即可。顺便说一句,调用
删除NullPtr
是可以的,因为它不需要任何事情。Your
Trie::clear()
method deletes the sameTrie
twice.The destructor
~Trie
callsclear(pair.second->map)
and then callsdelete pair.second
which is the same asclear(pair.second->map)
again sincedelete
calls the destructor of the pointed-at data. Callingclear()
twice on the same map means that the second call is trying to delete already deleted data, which causes the crash. Callingdelete
on a pointer does not change the value of the pointer, which is why thenullptr
check does nothing.Since the destructor calls
clear()
, theclear()
method does not need to explicitly call itself recursively. Just delete the map pointers.By the way, calling
delete nullptr
is fine since it is required to do nothing.