实例化对象时如何修复Segmentation Fault错误

时间:2019-02-19 09:57:43

标签: c++ class

我正在创建一些类,这些类可以一起模拟租车公司的功能。我可以使用这些类,并且可以创建每个类的对象,但是当我尝试运行以下代码时,出现了段错误,我不确定为什么。按此顺序声明对象时为什么会出现分段错误?

我尝试切换声明对象的顺序,错误消失了。如果我只用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;
}

1 个答案:

答案 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才能真正创建字符串的不同(“较深”)副本。