最近正在自己摸索想写个特别简单的小游戏:大富翁,使用C++和EasyX库实现,我简单描述一下我的程序结构和问题。
涉及的类有两个:Player类和Block类(地块),各自都有ID和name等基本属性。
目前暂时没有想到怎么兼容图像界面和在控制台输出游戏流程文字消息,所以只好在旁边开个同步的控制台。
基本上可以正常游戏,但是有两个问题研究了半天还是想不出解决方法:
①正常情况下,可以输出当前玩家的名字、骰子点数、玩家行为(比如购地,付钱,坐牢),但是偶尔会出现标题中“0xC000005,读取位置~~~时发生冲突”的问题,导致程序被迫暂停。
②整个游戏流程结束(最终场上只剩下一名角色),需要释放内存,在释放骰子对象dice的内存和四个角色对象player[4]的时候都没有问题,但是永远都不能释放block[28]的内存,每次都会报错,查了半天也不知道是什么问题……
③偶尔会出现“无可用源”或者和什么符号相关的错误,都是我没见过的,查也查不到怎么解决(可能是我还不会搜索)。
我知道我既没有贴代码也没有贴图片,让大家根本没法回答我的问题……很抱歉,因为我还不知道我多文件的代码怎样贴上来才会又让人有阅读欲又能做的有条理,如果大家能告诉我应该怎么提问也非常感谢。
0xC000005,读取位置~~~时发生冲突
这个应该是指针的问题,读取非法地址
能否把这部分代码给一下?
理论上我并没有移动这个指针,并且在main函数观察它的时候,开始和结束所申请的内存空间起始地址没有变过。我应该通过什么方式给代码呢?全部复制过来吗?(因为分为多文件所以我不太清楚什么方式比较好)
@南山安北辰:
能否使用调试工具,找到出错的行号和位置?
@计算机知识杂谈:
我今天抱着尝试的态度在前面写了这么一小段代码(Block是一个类):
Block* block= new Block[28];
block[0].~Block();
delete &block[1];
执行立刻报错,箭头停在第三行delete &block[1];的位置,然后马上就跳到了一个”无可用源“的界面。
但是我单独执行:
Block block1;
block1.~Block();
Block* block2 = new Block;
delete block2;
的时候又不报错了,可以正常运行,我真的很头大
@计算机知识杂谈: 我的部分代码如下:
//main.cpp
using namespace std;
int main() {
initgraph(16 * unit, 9 * unit, SHOWCONSOLE);
SetWindowText(GetHWnd(), "迷你大富翁");
drawMap();
Block* block= new Block[28];
Player* player=new Player[4];
Dice* dice=new Dice;
//player[0].setHuman();
doGame(player, block, dice);
delete dice;
delete[] player;
system("pause");
return 0;
}
//Block.h
//
// Created by Frankie on 2021-11-22.
//
class Block {
public:
Block();//构造函数
int getBlockID() const;
std::string getName() const;
void setOwner(Player* p);
Player* getOwner() const;
int getType() const;
int getPriceOwner();
int getPricePasser();
int getLevel() const;
void upgradeLevel();
void setBlank();
void draw() const;
static int bc;
private:
int blockID;
std::string name;
int type;//0-起点, 1-商业地块, 2-交通地块, 3-度假地块, 4-新闻地块, 5-公园地块, 6-人民法院
int X, Y;
Player* owner;
int basePrice;//对于商业地块来讲是基础费用,对于交通地块来讲即为一次性费用
int level;//商业地块的专属属性,等级
const float upgradeRate[4] = { 1, 0.5, 0.5, 1 };//商业地块的专属属性,代表每次升级,所有者需要支付的费用倍率
const float passingRate[4] = { 0.2, 0.5, 0.8, 1.2 };//商业地块的专属属性,代表每个等级,停留者需要支付的费用倍率
char fileName[7];//图像文件的名称
};
//Block.cpp
//
// Created by Frankie on 2021-11-22.
//
int Block::bc = 0;
Block::Block() {
blockID = bc;
name = blockName[bc];
type = blockType[bc];
X = blockX[bc];
Y = blockY[bc];
owner = nullptr;
basePrice = blockPrice[bc];
level = 0;
strcpy(fileName, blockFileName[bc]);
bc++;
draw();
}
int Block::getBlockID() const { return blockID; }
std::string Block::getName() const { return name; }
int Block::getType() const { return type; }
void Block::setOwner(Player* p) { owner = p; }
Player* Block::getOwner() const { return owner; }
int Block::getPriceOwner() { return basePrice * upgradeRate[level]; }
int Block::getPricePasser() { return basePrice * passingRate[level]; }
void Block::setBlank() {
level = 0;
owner = nullptr;
IMAGE imageB, imageL;
loadimage(&imageB, bannerGhost, unit, unit / 10);
putimage(X, Y, &imageB);
if (type == 1) {
loadimage(&imageL, levelGhost, unit / 4, unit / 4);
putimage(X, Y, &imageL);
}
}
int Block::getLevel() const { return level; }
void Block::upgradeLevel() { level++; }
void Block::draw() const {
IMAGE image;
loadimage(&image, fileName, unit, unit);
putimage(X, Y, &image);
}
@南山安北辰:
关于你之前的问题,不能delete &block[1]
我写这段代码试验了一下
using namespace std;
int main(){
int *p=new int[10];
delete &p[1];
}
运行错误,因为new分配的是连续的一块内存,不能单独释放一个对象(好像是这样?)
希望有用。
@计算机知识杂谈: 你好,我也尝试过了,确实连续内存需要用delete[]来释放。我本来的代码里就是用delete[]释放的,但是并没有成功,所以我猜测原因并不在这