我正在创建一些类,这些类可以一起模拟租车公司的功能。我可以使用这些类,并且可以创建每个类的对象,但是当我尝试运行以下代码时,出现了段错误,我不确定为什么。按此顺序声明对象时为什么会出现分段错误?
我尝试切换声明对象的顺序,错误消失了。如果我只用Car()
构造函数声明两辆车,那么问题也就解决了。如果我删除Car或Sensor类中的任何功能,该错误就会消失。
PS:几天前我问了这个问题,并且由于无法识别错误(远非完整,最小和可验证),所以包含了太多代码,但是这次我将其范围缩小为尽我所能。如果其中包含很多代码,我深表歉意,但是我已经删除了所有可能的代码,如果删除了更多代码,问题就消失了。
这是我的主文件:
#include "Car.h"
int main() {
char make[] = "Subaru", model[] = "Outback", name[] = "Brandon",
type[] = "radar";
Sensor sensors[3];
Sensor sensor1 = Sensor(type), sensor2 = Sensor(), sensor3 =
Sensor();
sensors[0] = sensor1;
sensors[1] = sensor2;
sensors[2]= sensor3;
Car car1 = Car();
Car car2 = Car(make, 155.81, sensors);
return 0;
}
我的汽车课:
#ifndef CAR_H
#define CAR_H
#include <iostream>
#include "MyString.h"
#include "Sensor.h"
using namespace std;
#define MAX_STR_SIZE 256
#define MAX_NUM_SNSRS 3
class Car {
public:
Car();
Car(char* make, float baseprice, Sensor* sensors);
void setMake(char* make);
void setBaseprice(float baseprice);
void setAvailable(bool available);
void setOwner(char* owner);
void updatePrice();
private:
char m_make[MAX_STR_SIZE];
Sensor m_sensors[MAX_NUM_SNSRS];
int m_numsensors;
float m_baseprice;
float m_finalprice;
bool m_available;
char m_owner[MAX_STR_SIZE];
};
#endif
#include "Car.h"
Car::Car() {
char dflt[] = {'\0'};
setMake(dflt);
setAvailable(true);
setOwner(dflt);
m_numsensors = 0;
setBaseprice(0.0);
}
Car::Car(char* make, float baseprice, Sensor* sensors) {
char dflt[] = {'\0'};
setMake(make);
setAvailable(true);
setOwner(dflt);
for(int i = 0; i < MAX_NUM_SNSRS; i++) {
(*(m_sensors + i)) = Sensor(*(sensors + i));
if(myStringCompare((sensors + i)->getType(), "none") != 0) {
m_numsensors++;
}
}
setBaseprice(baseprice);
}
void Car::setMake(char* make) {
myStringCopy(m_make, make);
}
void Car::setBaseprice(float baseprice) {
m_baseprice = baseprice;
updatePrice();
}
void Car::setAvailable(bool available) {
m_available = available;
}
void Car::setOwner(char* owner) {
myStringCopy(m_owner, owner);
}
void Car::updatePrice() {
float totSnsrPrice = 0.0;
for(int i = 0; i < m_numsensors; i++) {
totSnsrPrice += (m_sensors + i)->getCost();
}
m_finalprice = m_baseprice + totSnsrPrice;
}
我的传感器类:
#ifndef SENSOR_H
#define SENSOR_H
#include "MyString.h"
#define MAX_STR_SIZE 256
#define NUM_TYPES 5
class Sensor {
public:
Sensor();
Sensor(char* type);
char* getType();
float getCost();
void setType(char* type);
void setCost(float extraCost);
private:
char m_type[MAX_STR_SIZE];
float m_extracost;
};
#endif
#include "Sensor.h"
const char* validSensors[] = {"gps", "camera", "lidar", "radar",
"none"};
const float prices[] = {5.0, 10.0, 15.0, 20.0, 0.0};
Sensor::Sensor() {
char dflt[] = "none";
setType(dflt);
setCost(0.0);
}
Sensor::Sensor(char* type) {
int index = -1;
char dflt[] = "none";
for(int i = 0; i < NUM_TYPES; i++) {
if(myStringCompare(type, *(validSensors + i)) == 0) {
index = i;
}
}
if(index < 0) {
setType(dflt);
setCost(0.0);
} else {
setType(type);
setCost(*(prices + index));
}
}
char* Sensor::getType() {
return m_type;
}
float Sensor::getCost() {
return m_extracost;
}
void Sensor::setType(char* type) {
myStringCopy(m_type, type);
}
void Sensor::setCost(float extracost) {
m_extracost = extracost;
}
myStringCopy和myStringCompare只是典型的std :: string复制和比较函数,我们只是不允许使用它们(它们包含在MyString.h中,我已经使用了一段时间了,所以我知道他们按预期工作)。
我希望输出什么都没有,但是仍然成功,而不是分段错误。我在任何地方都找不到错误,将不胜感激。谢谢!
编辑:这是我要求的字符串类:
#ifndef MYSTRING_H
#define MYSTRING_H
int myStringCompare(const char* str1, const char* str2);
char* myStringCopy(char* destination, const char* source);
#endif
#include "MyString.h"
int myStringCompare(const char* str1, const char* str2) {
int index = 0;
while(*(str1 + index) != '\0' || *(str2 + index) != '\0') {
if(*(str1 + index) < *(str2 + index)) {
return -1;
}
if(*(str1 + index) > *(str2 + index)) {
return 1;
}
index++;
}
return 0;
}
char* myStringCopy(char* destination, const char* source) {
int index = 0;
while(*(source + index) != '\0') {
*(destination + index) = *(source + index);
index++;
}
*(destination + index) = '\0';
return destination;
}
答案 0 :(得分:1)
我们没有您的字符串类的完整详细信息,因此很难重现。
但是,当您调用sensors[0] = sensor1;
时,您正在复制Sensor
,但尚未定义赋值运算符(或与此相关的复制构造函数)。
您还可以在Car
构造函数中使用
(*(m_sensors + i)) = Sensor(*(sensors + i));
现在,如果您没有字符串类的全部详细信息,我可以提供一些可能有用的建议。
首先,设置传感器时要进行大量复制。
您可以折叠
Sensor sensors[3];
Sensor sensor1 = Sensor(type), sensor2 = Sensor(), sensor3 =
Sensor();
sensors[0] = sensor1;
sensors[1] = sensor2;
sensors[2]= sensor3;
向下
Sensor sensors[3]={{type}, {}, {}};
这可能无法解决问题,但值得关注的地方。
接下来,删除二传手。您可以使用委派构造函数将您拥有的两个结构绑定在一起,并避免使用它们。 这样可以避免某些副本。
非常仔细地查看深浅复制的内容。
如果您有两种char *
类型,
char * word = "Hello";
char * another_word = word;
第二个是“浅”副本。您需要等效的strcpy
才能真正创建字符串的不同(“较深”)副本。