我的park_car功能出了什么问题
What is wrong with my park_car function?
我又在为学校做一个任务,我正在慢慢实现它,我不知道为什么我的park_car
函数不起作用,我只是想进行测试,程序崩溃了......这是我的代码。
PS:我无法更改***p2parkboxes
,因为它像大多数其他变量一样在启动文件中给出。我只想看到楼层 0 的第一个元素为:HH-AB 1234。非常感谢您的帮助。PS2:我不能使用 std::string 以及该任务不允许使用。
#include <iostream>
#include <cstring>
using namespace std;
#define EMPTY "----------"
class Parkbox{
char *license_plate; // car's license plate
public:
Parkbox(char *s = EMPTY); // CTOR
~Parkbox(); // DTOR
char *get_plate(){return license_plate;}
};
class ParkingGarage{
Parkbox ***p2parkboxes;
//int dimensions_of_parkhouse[3]; // better with rows,columns,floors
int rows,columns,floors; // dimensions of park house
int total_num_of_cars_currently_parked;
int next_free_parking_position[3];
// PRIVATE MEMBER FUNCTION
void find_next_free_parking_position();
public:
ParkingGarage(int row, int col, int flr);// CTOR,[rows][columns][floors]
~ParkingGarage(); // DTOR
bool park_car(char*); // park car with license plate
bool fetch_car(char*); // fetch car with license plate
void show(); // show content of garage floor
// by floor
};
Parkbox::Parkbox(char *s ) { // CTOR
license_plate = new char[strlen(s)+1];
strcpy(license_plate, s);
//cout << "ParkBox CTOR" << endl;
}
Parkbox::~Parkbox() { // DTOR
delete [] license_plate;
//cout << "ParkBox DTOR" << endl;
}
ParkingGarage::ParkingGarage(int row, int col, int flr){
rows = row; columns = col; floors = flr;
p2parkboxes = new Parkbox**[row];
for (int i = 0; i < row; ++i) {
p2parkboxes[i] = new Parkbox*[col];
for (int j = 0; j < col; ++j)
p2parkboxes[i][j] = new Parkbox[flr];
}
}
ParkingGarage::~ParkingGarage(){
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < columns; ++j)
delete [] p2parkboxes[i][j];
delete [] p2parkboxes[i];
}
delete [] p2parkboxes;
}
void ParkingGarage::show(){
int i,j,k;
for (i = 0 ; i < floors; i++){
cout << "Floor" << i << endl;
for (j=0;j<rows;j++){
for (k=0;k<columns;k++){
cout << p2parkboxes[j][k][i].get_plate() << " ";
}
cout << endl;
}
}
}
bool ParkingGarage::park_car(char*s){
p2parkboxes[0][0][0] = Parkbox(s); //test
//p2parkboxes[0][0][0] = s; //test
return true;
}
int main(void) {
// a parking garage with 2 rows, 3 columns and 4 floors
ParkingGarage pg1(2, 3, 4);
pg1.park_car("HH-AB 1234");
/*pg1.park_car("HH-CD 5678");
pg1.park_car("HH-EF 1010");
pg1.park_car("HH-GH 1235");
pg1.park_car("HH-IJ 5676");
pg1.park_car("HH-LM 1017");
pg1.park_car("HH-MN 1111"); */
pg1.show();
/*pg1.fetch_car("HH-CD 5678");
pg1.show();
pg1.fetch_car("HH-IJ 5676");
pg1.show();
pg1.park_car("HH-SK 1087");
pg1.show();
pg1.park_car("SE-AB 1000");
pg1.show();
pg1.park_car("PI-XY 9999");
pg1.show(); */
return 0;
}
您没有为 Parkbox 类声明复制构造函数。所以,这条线
p2parboxes[0][0][0] = Parkbox(s)
在堆栈上创建一些东西(带有 char* 指针的 Parkbox 实例((并几乎立即删除它(。 要更正此问题,您可以定义
Parkbox& operator = Parkbox(const Parkbox& other)
{
license_plate = new char[strlen(other.get_plate())+1];
strcpy(license_plate, other.get_plate());
return *this;
}
让我们看看
p2parboxes[0][0][0] = Parkbox(s)
线。
- 首先,调用构造函数并在堆栈上创建Parkbox的实例(我们将此称为tmp_Parkbox(。
- 在此构造函数中,分配了license_plate,假设它指向0xDEADBEEF位置。
- 复制发生了(这是显而易见的,因为这是用代码编写的东西(,p2parbox[0][0][0] 现在包含tmp_Parkbox的确切副本。
- tmp_Parkbox的作用域现在结束,并调用tmp_Parkbox的析构函数,其中解除分配了 tmp_Parkbox.license_plate (0xDEADBEEF ptr(。 p2parbox[0][0
][0] 仍然包含 Parkbox 的"有效"实例,并且 p2parbox[0][0][0].license_plate 仍然0xDEADBEEF这会导致未定义的行为,如果在调用
cout <<p2parbox[0][0][0].license_plate;
底线:行本身没有问题,问题隐藏在"="运算符的实现细节中。
在这一点上,你最好对字符串使用 std::string,而不是将隐含的 C++ 复制/构造语义混合在一起的锋利、棘手和明确的 C 式直接内存管理。如果您将 std::vector 用于动态数组,代码也会更好。
这里的问题是你没有深度拷贝赋值语义。 将临时 Parkbox 分配给停车场中的 Parkbox 时,编译器生成的赋值运算符会创建指针license_plate的浅拷贝,使两个 Parkbox 指向相同的内存位置。 然后,临时 Parkbox 超出范围并删除license_plate。 由于另一个Parkbox指向同一位置,因此其license_plate也会被删除。
有几种解决方案。 解决此问题的一种方法是定义一个赋值运算符和一个复制构造函数,它们提供适当的语义,即执行牌照字符串的深层副本。 更好的选择,也是更好地利用C++的选择,是使用 std::string 而不是手动分配的 C 字符串。 我强烈建议使用第二种方法,尽管通过第一种方法可能会有所启发。
从 OP:
我解决了以下问题:
void Parkbox::change_plate(char *s){
delete [] license_plate;
license_plate = new char[strlen(s)+1];
strcpy(license_plate, s);
}
- 警告处理为错误这里有什么问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 当我尝试添加 2 个大字符串时,我无法弄清楚出了什么问题
- 违反const正确性:我应该现实地期待什么问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 我的逻辑反转字符串中的元音有什么问题?
- 需要以下代码的帮助,下面的代码有什么问题
- 常量公共成员有什么问题?
- 以下代码中的函数模板有什么问题?
- 这个返回元素位置的基于循环的函数有什么问题?
- creat_list2功能有什么问题?
- 格式说明符C++有什么问题
- 任何人都可以告诉我我的 C++ 代码出了什么问题?
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 我的堆栈和库存清单程序的结构有什么问题?
- 此工厂功能有什么问题?
- 以下 C++ 代码有什么问题?
- 数组为此合并排序函数提供了正确的输出,但向量给出了不正确的输出.出了什么问题?
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了