初始化整数成员变量会导致更改另一个成员变量的地址
Initializing an integer member variable results in changing another member variable's address
这对我来说似乎是一个相当奇怪的错误。我的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()
时出现段错误。
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
有人知道发生了什么吗?
代码的问题很可能是你试图访问未初始化的指针(b.floors
)。假设b
是这个复制构造函数的结果,那么b.floors
将指向随机内存。 然后,b.floors[i]
将指向比b.floors
指向的内存早几个字节的随机内存,最终您使用->
取消引用此随机地址,从而导致分段错误。
问题的解决方案是正确分配和复制楼层阵列:
floors = new Floor* [num_floors];
for (int i=0; i<num_floors; ++i)
floors[i] = b.floors[i];
您可能还希望将指向的对象复制到Floor
,具体取决于实现的详细信息。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 将包含C样式数组的对象初始化为成员变量(C++)
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在循环中按顺序遍历成员变量
- c++类声明时,相同的例程,不同的成员变量类型
- 如何从另一个文件继承私有成员变量和公共函数
- 在C++类中,是否必须初始化作为数组的成员变量
- 如何从子成员函数修改父公共成员变量
- 我可以在 C++ 中将数据成员/变量从其定义之外添加到结构中吗?
- 从私有成员变量的成员方法返回unique_ptr
- 在派生类中使用基类的私有成员变量的最佳方法
- 静态 constexpr 类成员变量对多线程读取是否安全?
- C++:是否可以使用非静态成员变量模板?
- 打印所有继承的类成员变量和方法
- 如何在复杂继承中访问静态成员变量
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 成员变量与函数概念检查