gpt4 book ai didi

C++ 指针和类层次结构导致段错误难题

转载 作者:太空狗 更新时间:2023-10-29 21:37:18 25 4
gpt4 key购买 nike

我试图找出一个小代码更改背后的段错误的根本原因。让我们从这个运行没有问题的简化代码版本开始:

#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 并使用 this->parent = parent;TailNode::addTo,有效。

我猜这与指针以及我滥用它们的方式有关。

您可以在 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”的成员变量,该变量也在其父类中定义'游戏对象'。

TailNode类中移除GameObject* parent的重定义后,它不再出现段错误。

提交解决问题:https://github.com/spajus/sdl2-snake/commit/a1808e7d2426b5aedd9ab3a4dc2aa38aa0225a95

关于C++ 指针和类层次结构导致段错误难题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38029311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com