我尝试在几个编译器上运行代码并得到不同的结果。我要么得到一些奇怪的退出代码,如
-1073741819 (0xC0000005)
或 free(): double free detected in tcache 2
,要么在调试时得到 SIGTRAP (Trace/breakpoint trap) SIGSEGV (Segmentation fault)
。
我 99% 确定问题是我释放了船舶数组两次。但是,当我不在两个播放器上运行 func() 两次或者更改代码中的其他任何内容时,为什么我不会收到错误消息? 到底是什么问题以及如何修复错误?
是的我使用动态数组而不是向量,因为我正在尝试练习和学习。 是的我知道这种内存分配方法会产生内存碎片,但我从不改变矩阵的大小,所以这应该不是问题。
代码:
struct point_t {
int x;
int y;
point_t();
};
point_t::point_t() {
this->x = 0;
this->y = 0;
}
struct ship_t {
int size;
point_t end_coords[2];
};
struct player_t {
int **map;
int map_size;
ship_t *ships;
int ships_count;
player_t(int, ship_t *, int);
~player_t();
};
player_t::player_t(int map_size, ship_t *ships, int ships_count) {
this->map = nullptr;
this->map_size = map_size;
this->ships = ships;
this->ships_count = ships_count;
}
player_t::~player_t() {
// Free map memory
// Free each column (sub-array)
for(int i = 0; i < map_size; i++) {
delete[] map[i];
}
// Free each row (array of pointers)
delete[] map;
map = nullptr;
map_size = 0;
delete[] ships;
ships = nullptr;
ships_count = 0;
}
void func(player_t &player) {
player.map = new int *[player.map_size];
for(int i = 0; i < player.map_size; i++) {
player.map[i] = new int[player.map_size];
for(int j = 0; j < player.map_size; j++) {
player.map[i][j] = 0;
}
}
}
int main()
{
ship_t *ships = new ship_t[(5 * 5) / 2];
for(int i = 0; i < 5; i++) {
ships[i].size = i + 1;
}
player_t player1 = player_t(5, ships, 5);
player_t player2 = player_t(5, ships, 5);
func(player1);
func(player2);
return 0;
}
使用 Visual Studio 运行代码可以让我:
HEAP CORRUPTION DETECTED: after Normal block (#72) at 0x00B065E8.
CRT detected that the application wrote to memory after end of heap buffer.
做
delete[] ships;
时。
由于
player_t
毁灭者摧毁了船只,因此您将船只的所有权授予 player_t
。但是您将同一个动态分配数组的所有权授予两个玩家。