释放内存时出错

Error freeing memory

本文关键字:出错 内存 释放      更新时间:2023-10-16

当我将一个具有动态内存的自定义类添加到向量中时,我遇到了一个奇怪的错误。

错误为

对象0x7fee9ac000e0出错:释放的指针未分配***在malloc_error_break中设置断点以调试

尝试添加具有动态内存的Symbol会产生错误,删除析构函数中的delete[] parameters会删除错误,但我认为会导致内存泄漏。

代码低于

//test.cpp
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include "symbol.h"
int main(int argc, char const *argv[])
{
    Symbol a('A');
    std::cout << a << std::endl;
    Symbol b('B',2);
    std::cout << b << std::endl;
    double p[3] = {1.2, 2.4, 4.8};
    Symbol c('C',3,p);
    std::cout << c << std::endl;
    Symbol* d = new Symbol('D',3,p);
    ////
    std::cout << *d << std::endl;
    std::vector<Symbol> axiom;
    axiom.push_back(a)
    axiom.push_back(b); // This lines produces the error
    delete d;
    return 0;
}
//symbol.h
#ifndef SYMBOL_H
#define SYMBOL_H
#include <iostream>
class Symbol{
    friend std::ostream& operator<<(std::ostream& output, const Symbol& s);
    private:
        char character;
        int numpar;
        double* parameters;
    public:
        Symbol();
        Symbol(const char c);
        Symbol(const char c, const int n);
        Symbol(const char c, const int n, const double p[]);
        ~Symbol();
        bool operator == (const Symbol &other) const;
};
#endif

//symbol.cpp
#include "symbol.h"
Symbol::Symbol()
{
    character = 0;
    numpar = 0;
}
Symbol::Symbol(const char c)
{
    character = c;
    numpar = 0;
}
Symbol::Symbol(const char c, const int n)
{
    character = c;
    if(n > 0)
    {
        numpar = n;
        parameters = new double[numpar];
        std::fill(parameters, parameters+numpar, 0.0);
    }
    else
    {
        numpar = 0;
    }
}
Symbol::Symbol(const char c, const int n, const double p[])
{
    character = c;
    if(n > 0)
    {
        numpar = n;
        parameters = new double[numpar];
        std::copy(p,p+numpar,parameters);
    }else{
        numpar = 0;
    }
}
Symbol::~Symbol()
{
    if(this->numpar > 0)
    {
        delete[] parameters; //If I comment this line the code runs smoothly but I think it produces memory leaks
    }
}
bool Symbol::operator==(const Symbol &other) const {
    if (character == other.character)
        return true;
    return false;
}
std::ostream& operator<<(std::ostream& output, const Symbol &s){
    output << s.character;
    if(s.numpar > 0)
    {
        output << '(';
        for(int i = 0 ; i < s.numpar-1 ; i++)
        {
            output << s.parameters[i] << ", ";
        }
        output << s.parameters[s.numpar-1] << ')';
    }
    return output;
}

您使用的是向量<Symbol>所以当你推送一个Symbol时,它实际上创建了一个新的Symbol,因为你没有定义一个复制构造函数,所以它只是复制字段,而不会提出任何问题。

因此,实际上有两个Symbol实例,它们的指针指向同一个参数数组,当其中一个被销毁时,另一个试图释放已经释放的东西。

请参阅:http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm

当您将持有动态内存的Symbol实例存储到向量中时:

axiom.push_back(b);

它是复制的。由于您还没有声明自己的复制构造函数,默认的复制构造函数将复制所有成员,因此现在两个实例拥有相同的double* parameters指针,并且它们最终都将尝试delete[]it。

如果使用std::vector<double> parameters,默认的复制构造函数将依赖于向量的复制构造函数,它将执行正确的操作™.

一般来说,最好依赖标准库类型来处理所有权问题。