智能指针 - 程序终止时的分段错误
Smart Pointers - Segmentation Fault at Program Termination
我一直在做一个 state-thingy 来替换我一直在使用的一些更糟糕的代码。我想尽可能现代,所以我在适当的地方使用 STL。我决定使用 unique_ptr
和 shared_ptr
,这是我以前从未使用过的。结果,我遇到了一个非常可怕的 运行-time 错误:munmap_chunk(): invalid pointer: 0x00007fff7b3f08e0
我只知道错误与 free()
和 malloc()
有关,但我没有在我的代码中使用了其中的任何一个,所以我假设它来自 STL 内部。更奇怪的是,如果我在 main 的开头放一个 std::cout << "Hello World!\n";
,我只会得到一个 Segmentation fault
到目前为止我的代码相对较小:
state.hpp:
#pragma once
#include "state_manager.hpp"
class state{
using manager_ptr = std::shared_ptr<state_manager>;
protected:
manager_ptr man;
public:
const manager_ptr manager() const;
void manager(manager_ptr&& parent_manager);
};
state.cpp:
#include "state.hpp"
const state::manager_ptr state::manager() const{
return man;
}
void state::manager(manager_ptr&& parent_manager){
man = parent_manager;
}
state_manager.hpp:
#pragma once
#include <stack>
#include <memory>
class state;
class state_manager{
using element = std::unique_ptr<state>;
using container = std::stack<element>;
protected:
container states;
public:
void push(element&& to_push);
void pop();
void change(element&& change_to);
};
state_manager.cpp:
#include "state_manager.hpp"
#include "state.hpp"
void state_manager::push(element&& to_push){
states.push(std::forward<element>(to_push));
states.top()->manager(std::shared_ptr<state_manager>(this));
}
void state_manager::pop(){
states.pop();
}
void state_manager::change(element&& change_to){
states.pop();
push(std::forward<element>(change_to));
}
main.cpp:
#include "state_manager.hpp"
#include "state.hpp"
#include <iostream>
int main(int argc, const char* argv[]){
state_manager test;
test.push(std::make_unique<state>());
test.change(std::make_unique<state>());
test.pop();
}
在这行代码中:
states.top()->manager(std::shared_ptr<state_manager>(this));
您正在构造一个指向 this
的 shared_ptr
。这意味着当 shared_ptr 的引用计数降为零时,它将 delete
this
。这很糟糕,因为 class 不是 this
的所有者。在你的例子中,this
指针甚至没有被 new
分配,所以 shared_ptr 将无法删除它。
您可以在 state_manager
class 中为 man
使用普通的 C++ 指针,因为它目前不需要指针的所有权。
或者,您需要一些其他方法来获得指向 this
的 shared_ptr
或 weak_ptr
,例如通过将其传递给 push
(这很奇怪)。
我一直在做一个 state-thingy 来替换我一直在使用的一些更糟糕的代码。我想尽可能现代,所以我在适当的地方使用 STL。我决定使用 unique_ptr
和 shared_ptr
,这是我以前从未使用过的。结果,我遇到了一个非常可怕的 运行-time 错误:munmap_chunk(): invalid pointer: 0x00007fff7b3f08e0
我只知道错误与 free()
和 malloc()
有关,但我没有在我的代码中使用了其中的任何一个,所以我假设它来自 STL 内部。更奇怪的是,如果我在 main 的开头放一个 std::cout << "Hello World!\n";
,我只会得到一个 Segmentation fault
到目前为止我的代码相对较小:
state.hpp:
#pragma once
#include "state_manager.hpp"
class state{
using manager_ptr = std::shared_ptr<state_manager>;
protected:
manager_ptr man;
public:
const manager_ptr manager() const;
void manager(manager_ptr&& parent_manager);
};
state.cpp:
#include "state.hpp"
const state::manager_ptr state::manager() const{
return man;
}
void state::manager(manager_ptr&& parent_manager){
man = parent_manager;
}
state_manager.hpp:
#pragma once
#include <stack>
#include <memory>
class state;
class state_manager{
using element = std::unique_ptr<state>;
using container = std::stack<element>;
protected:
container states;
public:
void push(element&& to_push);
void pop();
void change(element&& change_to);
};
state_manager.cpp:
#include "state_manager.hpp"
#include "state.hpp"
void state_manager::push(element&& to_push){
states.push(std::forward<element>(to_push));
states.top()->manager(std::shared_ptr<state_manager>(this));
}
void state_manager::pop(){
states.pop();
}
void state_manager::change(element&& change_to){
states.pop();
push(std::forward<element>(change_to));
}
main.cpp:
#include "state_manager.hpp"
#include "state.hpp"
#include <iostream>
int main(int argc, const char* argv[]){
state_manager test;
test.push(std::make_unique<state>());
test.change(std::make_unique<state>());
test.pop();
}
在这行代码中:
states.top()->manager(std::shared_ptr<state_manager>(this));
您正在构造一个指向 this
的 shared_ptr
。这意味着当 shared_ptr 的引用计数降为零时,它将 delete
this
。这很糟糕,因为 class 不是 this
的所有者。在你的例子中,this
指针甚至没有被 new
分配,所以 shared_ptr 将无法删除它。
您可以在 state_manager
class 中为 man
使用普通的 C++ 指针,因为它目前不需要指针的所有权。
或者,您需要一些其他方法来获得指向 this
的 shared_ptr
或 weak_ptr
,例如通过将其传递给 push
(这很奇怪)。