C ++:delete []错误,指针未分配

问题描述 投票:-1回答:2

我正在为一个实验室开发一个程序,我需要一些内存管理方面的帮助。我是C ++的新手,虽然我有其他语言的经验,但动态内存管理让我感到困惑。另外,因为这是针对实验室的,所以我不能使用std :: vector或智能指针,只能使用数组和指针。

首先,有一个“Vehicle”类,有一些描述它的属性(比如make,model等)。接下来,有一个“Showroom”类,其中包含一系列车辆:

Vehicle * m_vehicles;

后来,在构造函数中:

m_vehicles = new Vehicle[m_maxCapacity];

接下来是“经销商”课程,其中有一系列陈列室:

Showroom * m_showrooms;
...
m_showrooms = new Showroom[m_maxCapacity];

我的main()方法创建了一些车辆,将它们添加到陈列室,然后将它们添加到经销商处。在程序结束之前,一切都没有问题。当程序完成并删除对象时,会出现一些问题。由于经销商是最后创建的,因此首先删除它。它是析构函数调用delete[] m_showrooms;,而Showroom类中的析构函数调用delete[] m_vehicles;。所以,我希望当程序结束时,操作系统会删除经销商对象,​​这会删除陈列室对象,从而删除车辆对象。

但是,它无法正常工作。实验室要求我们使用已提供的帮助程序将内存泄漏标记为错误。当我的main()创建一个陈列室,添加车辆,创建经销商,然后将陈列室添加到经销商,当程序结束时,内存泄漏检测器给出错误,说:

delete[] error: pointer was not allocated!

我为经销商添加的每个展厅都会收到一次此错误。此外,还有一个奇怪的错误:如果经销商包含任何两个具有相同容量的陈列室,程序结束时会出现段错误。

如果我说“拧它”并从析构函数中删除所有delete [],程序运行没有段错误,但内存泄漏程序检测到泄漏并阻止我继续前进。

我究竟做错了什么?我对C ++中的动态内存有一些基本的误解吗?我读到每个new []应该与delete []匹配,这就是我所拥有的。我已经向TA询问了这个问题,她对如何解决这个问题一无所知。

编辑:这是一些相关的代码:

main.cpp中:

//array of vehicles to store
Vehicle vehicles[] =
        {
                Vehicle("Ford", "Mustang", 1973, 9500, 113000),
                Vehicle("Mazda", "CX-5", 2017, 24150, 5900),
                Vehicle("Dodge", "Charger", 2016, 18955, 9018),
                Vehicle("Telsa", "Model S", 2018, 74500, 31),
                Vehicle("Toyota", "Prius", 2015, 17819, 22987),
                Vehicle("Nissan", "Leaf", 2016, 12999, 16889),
                Vehicle("Chevrolet", "Volt", 2015, 16994, 12558),
         };
    // Showrooms to store the vehicles
        Showroom showroom("Primary Showroom",2);
        showroom.AddVehicle(&vehicles[0]);
        showroom.AddVehicle(&vehicles[1]);
        //showroom.AddVehicle(&vehicles[2]);

        Showroom secondary("Storeroom 2",4);
        secondary.AddVehicle(&vehicles[3]);
        secondary.AddVehicle(&vehicles[4]);
        secondary.AddVehicle(&vehicles[5]);
        secondary.AddVehicle(&vehicles[6]);

        // A "parent" object to store the Showrooms
        Dealership dealership("Dealership",2);
        dealership.AddShowroom(&showroom);
        dealership.AddShowroom(&secondary);
        //displays the showrooms and their contents
        dealership.ShowInventory();

Vehicle.cpp的相关功能:

Vehicle::Vehicle(std::string mk, std::string md, int yr, int pr, int ml) {
    make = mk;
    model = md;
    year = yr;
    price = pr;
    miles = ml;

}
Vehicle::~Vehicle() {}

Vehicle::Vehicle(const Vehicle &veh) {
    //year  = new int;
    make = veh.make;
    model = veh.model;
    year = veh.year;
    price = veh.price;
    miles = veh.miles;
}
Vehicle& Vehicle::operator=(const Vehicle &veh) {
    make = veh.make;
    model = veh.model;
    year = veh.year;
    price = veh.price;
    miles = veh.miles;
    return *this;
}
Vehicle::Vehicle() {}

来自Showroom.cpp:

//copy constructor
Showroom::Showroom(const Showroom &s)
{
    m_name = s.m_name;
    m_maxCapacity =s.m_maxCapacity;
    m_currentNumberOfVehicles = s.m_currentNumberOfVehicles;
    m_vehicles = new Vehicle[m_maxCapacity];

    for (int i = 0; i< s.m_currentNumberOfVehicles;i++)
    {
        m_vehicles[i] = *new Vehicle(s.m_vehicles[i]);
    }
}
//normal constructor
Showroom::Showroom(std::string name, unsigned int maxCapacity) {
    m_name = name;
    m_maxCapacity = maxCapacity;
    m_vehicles = new Vehicle[m_maxCapacity];

    m_currentNumberOfVehicles = 0;

}
Showroom::~Showroom() {
    delete[] m_vehicles;

}
Showroom::Showroom(){}

来自Dealership.cpp:

//copy constructor
Dealership::Dealership(const Dealership &d)
{
    m_name = d.m_name;
    m_maxCapacity =d.m_maxCapacity;
    m_currentNumberOfShowrooms = d.m_currentNumberOfShowrooms;
    m_showrooms = new Showroom[m_maxCapacity];

    for (int i = 0; i< d.m_currentNumberOfShowrooms;i++)
    {
        m_showrooms[i] = *new Showroom(d.m_showrooms[i]);
    }
}
//normal constructor
Dealership::Dealership(std::string name, unsigned int capacity) {
    m_name = name;
    m_maxCapacity = capacity;
    m_currentNumberOfShowrooms = 0;
    m_showrooms = new Showroom[m_maxCapacity];
}
Dealership::~Dealership() {
    //std::cout<<"Deleting dealership " <<m_name << std::endl;
    delete[] m_showrooms;
    //m_showrooms = 0;

}

编辑2:这是main()中最小的代码量,它给出了错误,说我试图释放未分配的指针:

Showroom sh("Name", 0);

    Dealership dealer("dealer", 1);
    dealer.AddShowroom(&sh);

这是段错误的最小代码量:

Showroom sh("Name", 0);
    Showroom sh2("Showroom 2",0);
    Dealership dealer("dealer", 2);

    dealer.AddShowroom(&sh);
    dealer.AddShowroom(&sh2);

这里是AddShowroom(),供参考:

void Dealership::AddShowroom(const Showroom *showroom) {

    m_showrooms[m_currentNumberOfShowrooms] = *showroom;
    m_currentNumberOfShowrooms++;
}
c++ pointers memory-management
2个回答
0
投票

这些行保证内存泄漏:

m_vehicles[i] = *new Vehicle(s.m_vehicles[i]);

和:

m_showrooms[i] = *new Showroom(d.m_showrooms[i]);

这是动态分配,解除引用和使用解除引用的值来将赋值复制到数组中。但是指向原始动态分配值的指针会立即丢失;你分配它的瞬间泄漏了内存。

你真的想要:

m_vehicles[i] = Vehicle(s.m_vehicles[i]);

和:

m_showrooms[i] = Showroom(d.m_showrooms[i]);

由于显而易见的原因,您的segfaulting代码出错了:

Dealership dealer("dealer", 1);

声称最多会分配一个陈列室,然后你两次调用AddShowroom,并注销已分配内存的末尾(可能会破坏堆,谁知道还有什么)。

我不能肯定地说它为什么抱怨未分配的指针,但是你有很多泄漏和出界的错误,你的代码被遗漏了很多,很难说我没有' t错过了什么,与错误的代码是没有检查。您遇到的那种错误可能是由于堆损坏(您肯定会在不同时间造成的)或双重delete[]ing指针引起的。没有明显的代码这样做,但你没有提供MCVE(你提供的既不是最小也不完整),所以它可能是隐藏的。


1
投票

您的代码存在许多问题,并且它们都可能以某种方式导致段错误。

要添加@ShadowRanger指出的内容,shsh2不会动态分配,而dealer会保留对它们的引用。当这两个对象超出范围时会自动销毁。因此,当发生这种情况时,dealer将对不再存在的对象进行操作,并且随后会出现分段错误。

我看到分段错误的另一个原因是由于m_showrooms在超出容量时没有调整大小。线m_showrooms = new Showroom[m_maxCapacity];m_maxCapacity指针分配Showroom槽数。当你打电话给AddShowroom时,你需要检查是否会超过这个容量。如果是这样,你需要分配一个更大的数组,移动对象,然后销毁旧数组(而不是它所包含的对象)。

据我所知,您似乎不熟悉C ++中如何处理内存的想法。我建议花时间去弄清楚这一点,因为它会为你节省很多麻烦。

© www.soinside.com 2019 - 2024. All rights reserved.