c++指针和类层次结构导致段错误难题
C++ pointers and class hierarchy causing a segfault puzzler
我正试图找出一个小代码更改背后的段错误的根本原因。让我们从这个简化版本的代码开始,它的运行没有问题:
#include <iostream>
#include <string>
#include <vector>
class GameObject {
public:
virtual void update();
void addChild(GameObject* child);
GameObject* parent;
std::vector<GameObject*> children;
int x;
int y;
};
class Player : public GameObject {
public:
void growTail();
void update();
};
class TailNode : public GameObject {
public:
void addTo(GameObject* parent);
void update();
// UPDATE AFTER ANSWER IS CLEAR: this was in original codebase and it was causing the segfault
GameObject* parent;
};
void GameObject::addChild(GameObject* child) {
this->children.push_back(child);
child->parent = this; // <- can't do this in full codebase, causes segfault later
}
void GameObject::update() {
for (GameObject* child : children) {
child->update();
}
}
void Player::update() {
GameObject::update();
std::cout << "Player at: ["
<< std::to_string(x)
<< std::to_string(y)
<< "]"
<< std::endl;
}
void Player::growTail() {
TailNode* tail = new TailNode();
tail->addTo(this);
}
void TailNode::update() {
GameObject::update();
std::cout << "Tail parent at: ["
<< std::to_string(parent->x) // <- if parent is set inside GameObject::addChild, this segfaults in full codebase
<< std::to_string(parent->y)
<< "]"
<< std::endl;
}
void TailNode::addTo(GameObject* parent) {
parent->addChild(this);
// this->parent = parent; <-- have to do this to avoid segfault in full codebase
}
int main() {
Player* player = new Player();
player->x = 10;
player->y = 11;
player->growTail();
player->update();
}
现在,在游戏源本身中,它发生了段错误,因为尾部节点显然得到了一个坏的父节点。
当我将child->parent = this;
从GameObject::addChild
移开,并在TailNode::addTo
处使用this->parent = parent;
时,它起作用了。
我猜这与指针和我滥用它们的方式有关。
您可以在https://github.com/spajus/sdl2-snake/tree/tail_working找到完整的工作代码库以及破坏它的提交:https://github.com/spajus/sdl2-snake/commit/4e92e9d6823420ce7554f2b6d7d19992c48d4acc
我正在编译并运行它在OS X 10.11.5,
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.5.0
Thread model: posix
代码依赖于SDL2和它的一些扩展。
编译命令示例:$XCODE/XcodeDefault.xctoolchain/usr/bin/c++
-I/Library/Frameworks/SDL2.framework/Headers
-I/Library/Frameworks/SDL2_image.framework/Headers
-I/Library/Frameworks/SDL2_mixer.framework/Headers
-I/Library/Frameworks/SDL2_ttf.framework/Headers
-I$HOME/Dev/sdl2-snake/include
-Wall -Wextra -pedantic -std=c++11
-Wall -Wextra -pedantic -std=c++11
-g -g -o CMakeFiles/Snake.dir/src/main.cpp.o
-c $HOME/Dev/sdl2-snake/src/main.cpp
我知道你会建议使用智能指针而不是裸指针,你可能是对的,但在这里我只是玩得开心,我很好奇为什么它会这样。这可能很难重现(虽然有构建脚本),但也许一个有经验的c++开发人员会立即发现问题。
同时,我很感激你的代码审查和改进建议,我的c++技能接近于零,因为我从大学毕业后就没有用它做过任何事情了。
多亏了orbitcowboy的提示,我使用了立即发现问题的cppcheck
:
[include/snake/tail_node.hpp:13] -> [include/snake/game_object.hpp:18]:(警告)类'TailNode'定义的成员变量名称'parent'也定义在它的父类'GameObject'中。
从TailNode
类中删除GameObject* parent
的重定义后,它不再出现段错误。
提交修复问题:https://github.com/spajus/sdl2-snake/commit/a1808e7d2426b5aedd9ab3a4dc2aa38aa0225a95
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- c++指针和类层次结构导致段错误难题