涉及继承的问题,指针对象的释放以及何时执行此操作

时间:2017-04-27 17:53:51

标签: c++ pointers object inheritance

我目前正在编程班,发现教师不善于传达如何使用我们所教授的概念。我已经搜索了有关我主题的多个问题,但无法从中得到很多帮助。对不起,如果其中一些看似相似。

1)当处理父/子对象时,假设你有一个类VehicLot,它将车辆对象子(摩托车对象,汽车对象,卡车对象)和这些对象的数量添加到vector <Vehicle*> lot。在诸如此类的场景中,我似乎无法理解发生了什么。我不确定我是否也能正确解除分配。 (我已经想到了这个问题,如果这看起来像一个愚蠢的例子,那就很抱歉。这几乎是几周前我遇到麻烦的情况。)

void VehicLot::addVehic(int typeNum, int numVehic) {
    if(typeNum == 1){
        Car* newCar = new Vehicle();
        for(int i = 0; i < numVehic; i++)
            lot.push_back(newCar);
    delete newCar;
    newCar = NULL;
    }
}

所以,在这段代码中,这是否正确地添加了Car(这将是#1中的类型)对象所以车辆的向量?如果是这样,我是否也正确地释放了内存?很抱歉,如果这些代码中的任何一个代码在其他方面都不正确,我会想到这一点来模拟那些让我困惑的地方。是否临时创建新对象&#34;使用&#34;类函数将数据存储在其他东西中?为了进一步解释这个问题,我是否会将这些临时车辆对象单独添加到一个实际上可以保存数据以供以后使用的向量中?这些问题导致问题2。

2)到目前为止,我在计算机科学中遇到的最大问题之一是seg故障。经过一些研究,我发现这通常是因为访问了那些不存在的记忆。&#34;这是一种合理的描述方式吗?你能否提出一些关于我应该搜索哪些与seg故障有关的提示?由于我删除指针的概念看起来有点模糊,我假设我的问题在于没有正确删除指针/对象。

由于我正在学习这门课程,我应该补充一点,我不知道很多&#34;快捷方式&#34;我在这里见过的。我需要理解我的问题,但也能够按照我对我的期望做事。我真的很感激任何帮助,因为我做了大量的研究但却无法理解我必须改进的地方。

2 个答案:

答案 0 :(得分:2)

  

经过一些研究后我发现这通常是因为访问的内存不是“那里”。

这意味着您正在访问编译器为您的程序分配的内存之外的内存。

当你声明一个数组时,假设int arr[3],你的编译器在内存中保留3个空格,每个空格长8个字节。现在,这个存储空间可以在任何地方;在此之后的内存块可能被分配给某些内部计算机进程。当你不小心试图访问它时,(比如说arr[5]),你正在寻找应该超出界限的内存。如果该内存块为空,程序将继续正常运行。但是,如果它是为另一个进程保留的,则会遇到seg错误。

这就是为什么它被称为未定义的行为;如果您的代码触及无法访问的内存,您可能会遇到段故障,或者如果程序在空内存上踩踏,您的程序可能会继续运行。但两者都是错误的,你的数组不应该超出范围。

希望这有帮助

答案 1 :(得分:1)

在您的示例代码中,您创建了一个Vehicle对象,然后将numVehic指针复制到该向量中,然后删除所有这些指针指向的对象矢量。因此,向量中的所有指针都指向不再有效的内存。

假设您希望独立在向量中使用,那么您应该做的是

void VehicLot::addVehic(int typeNum, int numVehic) {
    if(typeNum == 1){
        for(int i = 0; i < numVehic; i++) {
            lot.push_back(new Car{});
        }
    }
}

如果不更改包含lot成员变量的类的析构函数,则会导致内存泄漏。所以你需要调整该类的析构函数来遍历向量中的所有元素并在它们上面调用delete,这看起来与此类似

~ClassThatContainsLotVariable::ClassThatContainsLotVariable() {
    for (auto vehicle : lot) {
        delete vehicle;
    }
}

然而,最好的解决方案是将lot的定义更改为std::vector<std::unique_ptr<Vehicle>>,这样您根本不需要关心内存管理 - 编译器生成的默认解构器保存lot成员变量的类将自动为您执行清理。此外,它还有助于识别您意外共享同一对象的位置(这是您的示例中发生的情况,如前所述),因为您无法复制unique_ptr。