使用 -> 运算符后 C++ 程序崩溃
Posted
技术标签:
【中文标题】使用 -> 运算符后 C++ 程序崩溃【英文标题】:C++ Program crashes after using -> Operator 【发布时间】:2013-11-28 17:33:14 【问题描述】:我正在做一个用 C++ 设计游戏的项目,当我尝试从玩家那里获得动作时,我的程序不断崩溃。该程序允许用户为这两个玩家中的每一个选择是计算机玩家还是人类玩家。如果是人类玩家,它会收集玩家的名字。
程序启动时,我的主类创建一个游戏对象,运行 selectPlayers() 函数,然后运行 play() 函数。程序正在加载,向我询问每个玩家的人或计算机,收集人名并显示棋盘(显示在 play() 函数中,然后崩溃并弹出一个带有消息的窗口
程序停止工作,windows 正在寻找解决方案
在下面的代码中添加了注释以显示问题所在。如果我在该行上方放置一个 cout 它会打印,但在该行之后没有任何内容打印...如果我在 HumanPlayer 类的 makeMove 方法的第一行放置一个 cout,它不会被打印,所以程序在进入方法之前崩溃。
这是我的游戏类的标题:
#include "Board.h"
#include "Player.h"
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED
class Game
Board b;
int turn;
bool winner;
Player* player1;
Player* player2;
public:
Game();
~Game();
void selectPlayers();
Player* nextPlayer() const;
void play();
void announceWinner();
;
#endif // GAME_H_INCLUDED
还有课程本身:
#include "Game.h"
#include "HumanPlayer.h"
#include "RandomPlayer.h"
#include <iostream>
Game::Game()
b.reset();
turn = 1;
winner = false;
Game::~Game()
void Game::selectPlayers()
int x = 0;
std::string type;
std::string name;
std::cout << "Enter type for Player 1 (Human/Computer): ";
std::cin >> type;
while(x == 0)
if(type.compare("Human") == 0)
x = 1;
std::cout << "Enter name for Player 1: ";
std::cin >> name;
HumanPlayer p(name, LIGHT);
HumanPlayer * player1 = &p;
else if(type.compare("Computer") == 0)
x = 1;
RandomPlayer p(1, LIGHT);
RandomPlayer * player1 = &p;
else
std::cout << "Please enter Human or Computer for Player 1: ";
std::cin >> type;
std::cout << "Enter type for Player 2 (Human/Computer): ";
std::cin >> type;
x = 0;
while(x == 0)
if(type.compare("Human") == 0)
x = 1;
std::cout << "Enter name for Player 2: ";
std::cin >> name;
HumanPlayer p(name, DARK);
HumanPlayer * player2 = &p;
else if(type.compare("Computer") == 0)
x = 1;
RandomPlayer p(2, DARK);
RandomPlayer * player2 = &p;
else
std::cout << "Please enter Human or Computer for Player 2: ";
std::cin >> type;
Player* Game::nextPlayer() const
void Game::play()
while(winner == false)
b.display();
if(turn%2 == 1)
player1->makeMove(b); //PROGRAM CRASHES HERE
++turn;
else
player2->makeMove(b);
++turn;
void Game::announceWinner()
任何帮助都会很棒,谢谢大家。
【问题讨论】:
【参考方案1】:您需要像这样更改所有代码:
HumanPlayer p(name, LIGHT);
HumanPlayer * player1 = &p;
到这里:
player1 = new HumanPlayer (name, LIGHT);
在您的代码中,您创建了一个局部变量,并为它分配了一些东西。类中的成员变量永远不会被初始化。
【讨论】:
别忘了在析构函数中删除这些!或者只使用智能指针,例如std::unique_ptr
或 std::shared_ptr
。【参考方案2】:
发生崩溃是因为player1
是一个野指针(即它不包含合法值)。您似乎正在尝试为其赋值,但操作不正确,如下所示:
HumanPlayer p(name, LIGHT);
HumanPlayer * player1 = &p;
这里有两个问题。首先,你声明的对象是一个局部变量,所以试图存储一个指向它的指针是一个很大的错误。它超出范围并在几行内被破坏。其次,您在这里声明了一个完全独立的player
指针,而不是使用属于该类成员的指针。结果是你将一个局部变量存储在一个局部指针中,所以你的程序以后就没有什么可使用的了。
相反,这些行应该在堆(或空闲存储)上实例化播放器类的新实例。传统的 C++ 会像这样使用“新”运算符:
player1 = new HumanPlayer(name, LIGHT);
但是,如果您使用的是现代编译器,那么您确实应该使用智能指针。这意味着您的 Game
类应该像这样声明指针:
std::shared_ptr<Player> player1;
分配给它们的代码应该是这样的:
player1 = make_shared<HumanPlayer>(name, LIGHT);
显然,您还需要对 player2
进行类似的更改。
【讨论】:
【参考方案3】:您永远不会在 Game.selectPlayers()
中初始化 player1
或 player2
。相反,您创建一个 新的临时 变量 Human
或 Random
Player
类型,在方法结束后超出范围。
【讨论】:
【参考方案4】:由于您没有初始化指针,因此您的类中有未初始化的数据。将它们设置为 NULL
或使用指针交换器(shared_ptr
、unique_ptr
)来管理它们,因为它们会为您处理初始化。
与 C# 或 Java 等语言不同,C++ 不会将成员变量设置为默认值,除非它们有默认构造函数,而指针则没有!
【讨论】:
以上是关于使用 -> 运算符后 C++ 程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
怎么用c++编写一个Windows服务程序来监控另一个程序,崩溃后重新启动。