【发布时间】:2012-09-26 02:45:46
【问题描述】:
这对我来说似乎是一个相当奇怪的错误。我的 C++ 程序出现段错误,我发现使用 GDB 时有些奇怪。我有以下构造函数和复制构造函数:
Bank::Bank(char mode, int floor_dimensions_, int num_floors_) : floor_dimensions(floor_dimensions_), num_floors(num_floors_) {
for (int i = 0; i < num_floors; i++) {
floors[i] = new Floor(floor_dimensions);
}
if (mode == 'M') {
read_map(floors);
} else if (mode == 'C') {
read_coords(floors);
}
}
Bank::Bank(const Bank& b) {
floor_dimensions = b.floor_dimensions;
num_floors = b.num_floors;
cout << floor_dimensions << endl;
cout << num_floors << endl;
for (int i = 0; i < num_floors; i++) {
floors[i] = new Floor(*b.floors[i]);
floors[i]->print_map();
}
这个类的定义是这样的
class Bank {
/** The number of floors the bank has */
int num_floors;
/** The dimension of each of the floors */
int floor_dimensions;
/** The floors in the bank */
Floor* floors[];
private:
Bank(char mode, int floor_dimensions_, int num_floors_);
Bank(const Bank& bank);
~Bank();
void read_map(Floor** floor);
void read_coords(Floor** floor);
}
现在我使用 GDB 在构造函数的第一行设置断点。执行完后面两行,b.floors[1]的值发生了变化,导致我调用b.floors[i]->foo()时出现segfault。
Breakpoint 1, Bank::Bank (this=0x7fffffffe050, b=...) at bank.cpp:29
29 floor_dimensions = b.floor_dimensions;
(gdb) p b.floors[0]
$4 = (Floor *) 0x610070
(gdb) p b.floors[1]
$5 = (Floor *) 0x6103f0
(gdb) p b.floors[2]
$6 = (Floor *) 0x610770
(gdb) n
30 num_floors = b.num_floors;
(gdb) p b.floors[0]
$7 = (Floor *) 0x610070
(gdb) p b.floors[1]
$8 = (Floor *) 0x8006103f0
(gdb) p b.floors[2]
$9 = (Floor *) 0x610770
(gdb) n
32 cout << floor_dimensions << endl;
(gdb) p b.floors[0]
$10 = (Floor *) 0x610070
(gdb) p b.floors[1]
$11 = (Floor *) 0x800000003
(gdb) p b.floors[2]
$12 = (Floor *) 0x610770
有人知道发生了什么吗?
【问题讨论】:
-
Floor* floors[];是无效的语法。此外,您没有复制数组,因此您可能在每次销毁对象时释放相同的指针。 -
@SethCarnegie 那么我将如何创建一个指针数组呢?而且我也没有故意放代码来复制数组。
-
为什么省略了数组复制代码?这是最可能的错误来源!
-
另外——为什么要在源代码上调用 foo()——因为类 decl 中缺少这个
-
@AdrianCornish 我在哪里修改它? AndrewShepherd 代码按照我提供的方式崩溃,其中 foo 是任何函数(甚至是空函数)。
标签: c++ pointers gdb segmentation-fault