在 unique_ptr 上调用重置后出现分段错误
Segmentation fault after calling reset on unique_ptr
我在 unique_ptr:
上调用重置时出现分段错误
Node* tree::left_rotate(Node* node) {
Node* temp = node->right.get();
node->right.reset(temp->left.get());
temp->left.reset(node); // **Here is segmentation fault happens**
if(node->right.get()) {
node->right->parent = node;
}
temp->parent = node->parent;
if(node->parent) {
if(node == node->parent->left.get()) {
node->parent->left.reset(temp);
node->parent = node->parent->left.get();
} else if(node == node->parent->right.get()) {
node->parent->right.reset(temp);
node->parent = node->parent->right.get();
}
}
return temp;
}
节点具有以下结构:
class Node {
public:
int data;
Node* parent;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
public:
Node() : data(0) {
}
explicit Node(int d) : data(d),
parent(nullptr),
left(nullptr),
right(nullptr) {}
};
gdb 报告:
Thread 1 received signal SIGSEGV, Segmentation fault. 0x00404ae5 in
std::unique_ptr >::~unique_ptr (
this=0xfeeefefa, __in_chrg=)
at C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:273
273 if (__ptr != nullptr)
来自上层堆栈帧的报告:
#2 0x004047e8 in std::default_delete<Node>::operator() (this=0xfe1de4,
__ptr=0xfeeefeee)
at C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:81
81 delete __ptr;
看来这里是双删。如何解决这个问题?也许值得将临时指针作为 shared_ptr?
Node* temp = node->right.get();
temp 是指向节点右节点的原始指针
node->right.reset(temp->left.get());
节点的右节点重置为temp的左节点,因此原始节点的右节点(temp指向的节点)被删除。这意味着临时原始指针现在指向已删除的节点。
temp->left.reset(node); // **Here is segmentation fault happens**
随着临时文件被删除,取消引用它以获得它的左节点会导致不好的事情。
一个快速的想法,也许首先使用 release() 而不是 get() 来接管节点右节点的所有权?
我在 unique_ptr:
上调用重置时出现分段错误Node* tree::left_rotate(Node* node) {
Node* temp = node->right.get();
node->right.reset(temp->left.get());
temp->left.reset(node); // **Here is segmentation fault happens**
if(node->right.get()) {
node->right->parent = node;
}
temp->parent = node->parent;
if(node->parent) {
if(node == node->parent->left.get()) {
node->parent->left.reset(temp);
node->parent = node->parent->left.get();
} else if(node == node->parent->right.get()) {
node->parent->right.reset(temp);
node->parent = node->parent->right.get();
}
}
return temp;
}
节点具有以下结构:
class Node {
public:
int data;
Node* parent;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
public:
Node() : data(0) {
}
explicit Node(int d) : data(d),
parent(nullptr),
left(nullptr),
right(nullptr) {}
};
gdb 报告:
Thread 1 received signal SIGSEGV, Segmentation fault. 0x00404ae5 in std::unique_ptr >::~unique_ptr ( this=0xfeeefefa, __in_chrg=) at C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:273 273 if (__ptr != nullptr)
来自上层堆栈帧的报告:
#2 0x004047e8 in std::default_delete<Node>::operator() (this=0xfe1de4, __ptr=0xfeeefeee) at C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:81 81 delete __ptr;
看来这里是双删。如何解决这个问题?也许值得将临时指针作为 shared_ptr?
Node* temp = node->right.get();
temp 是指向节点右节点的原始指针
node->right.reset(temp->left.get());
节点的右节点重置为temp的左节点,因此原始节点的右节点(temp指向的节点)被删除。这意味着临时原始指针现在指向已删除的节点。
temp->left.reset(node); // **Here is segmentation fault happens**
随着临时文件被删除,取消引用它以获得它的左节点会导致不好的事情。
一个快速的想法,也许首先使用 release() 而不是 get() 来接管节点右节点的所有权?