简体   繁体   English

“没有分配被释放的指针”

[英]“pointer being freed was not allocated”

#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <sstream>

using namespace std;

class CFile {
public:
    CFile(string filename); 
    ~CFile();               
    void ReadFile();         
    void WriteFile(string outputFilename);   
    void Calculate();   
    string  m_filename;
    int     m_numberInput;
    double* m_xData;         
    double* m_yData;
    int     m_numberOutput;
    double* m_xDataOut;     
    double* m_yDataOut;
};

CFile::CFile(string filename)
{
    m_filename = filename;
    string line;             
    ifstream myfile(m_filename.c_str());

    if (myfile.is_open())     
    {
        getline(myfile,line);    
        myfile.close();          
        stringstream Str;        
        Str << line; 
        Str >> m_numberInput;
        m_xData = new double[m_numberInput];  
        m_yData = new double[m_numberInput];
        cout << sizeof(m_xData) / sizeof(m_xData[0]) << endl;
    }
    else cout << "Unable to open file.\n";  
}

CFile::~CFile()
{ 
    delete[] m_xData; 
    delete[] m_yData;                                  
    m_xData = 0;                                 
    m_yData = 0;
    delete[] m_xDataOut; 
    delete[] m_yDataOut;                                  
    m_xDataOut = 0;                                 
    m_yDataOut = 0;
}

void CFile::ReadFile()
{
    ifstream infile(m_filename.c_str());
    string line;

    if (infile.is_open())
    {
        int x, y, i = 0;

        while (getline(infile,line))
        {
            infile >> x >> y;
            m_xData[i] = x;
            m_yData[i] = y;
            i++;
        }
        infile.close();
    }
    else cout << "Unable to open file.\n"; 
}

void CFile::WriteFile(string outputFilename)
{
    ofstream outfile(outputFilename.c_str());

    if (outfile.is_open())
    {
        for(int i=0; i < m_numberInput; i++)
            outfile << m_xDataOut[i] << " " << m_yDataOut[i] << endl;

        outfile.close();
    }
    else cout << "Unable to open file.\n"; 
}

void CFile::Calculate()
{
    m_xDataOut = new double[m_numberInput]; 
    m_yDataOut = new double[m_numberInput];

    for(int i=0; i < m_numberInput; i++)
    {
        m_xDataOut[i] = m_xData[i];
        m_yDataOut[i] = sqrt(m_yData[i]);
    }
}


int main()
{
    CFile file("Input.dat");
    file.ReadFile(); 
    file.Calculate(); 
    file.WriteFile("Output.dat");
    file.~CFile();
}

The error message is as follows: 错误消息如下:

main(11915,0x7fff77d3d310) malloc: *** error for object 0x7f8a99403940: pointer 
being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

This is code which ironically worked well some weeks ago. 这是几周前具有讽刺意味的代码。 I change OS and compilers and now it doesn't anymore. 我改变了OS和编译器,现在它不再了。 I read about this error in other threads, but couldn't really understand how to use the solutions on my code. 我在其他线程中读到了这个错误,但无法真正理解如何在我的代码中使用解决方案。 The code reads in a data file, does sth. 代码读入数据文件,确实如此。 with it and then writes the changed values into another file. 使用它然后将更改的值写入另一个文件。 Where is the allocation error? 分配错误在哪里? Thank you very much in advance for your help! 非常感谢您的帮助! :-) :-)

Your Destructor is called twice. 您的析构函数被调用两次。 You call it explicitly, and it is also called when exiting main(). 您可以显式调用它,并在退出main()时调用它。 You should remove your explicit destrcutor call. 你应该删除你的显式destrcutor调用。

Two problems: 两个问题:

  • You don't necessarily initialise all four pointers, in which case it's not safe to apply delete to them. 您不必初始化所有四个指针,在这种情况下,对它们应用delete是不安全的。 You can fix this by initialising them to null before doing anything; 您可以在执行任何操作之前将它们初始化为null来解决此问题; or, better still, replace them with std::vector<double> so you don't have to mess around with delete at all. 或者,更好的是,用std::vector<double>替换它们,这样你就不必乱用delete了。 That will also fix the class's invalid copy semantics (it breaks the Rule of Three ) and the potential memory leaks if construction fails. 这也将解决该类的无效复制语义(这将打破规则 ),并且如果构造失败,则可能导致内存泄漏。
  • You're calling the destructor manually ( file.~CFile() , at the end of main ). 你手动调用析构函数( file.~CFile() ,在main的末尾)。 Don't do that: the destructor is called automatically when the program leaves the variable's scope, and it's an error to call it twice. 不要那样做:当程序离开变量的作用域时会自动调用析构函数,并且调用它两次是错误的。

As @claptrap pointed out your memory managements were also buggy. 正如@claptrap指出你的记忆管理也是错误的。

  1. You should migrate to std::vector<double> rather than raw double arrays and pointers. 您应该迁移到std::vector<double>而不是原始的double数组和指针。 You can think of vec.resize(N) as a variant of new double[N] which never needs an explicit delete[] . 您可以将vec.resize(N)视为new double[N]的变体,它永远不需要显式delete[]

  2. If you are on Linux, it's a good practice to run your program under valgrind which automatically traces memomry allocations/deallocations and points out any invalid memory operations. 如果您使用的是Linux,则最好在valgrind下运行程序,该程序会自动跟踪内存分配/取消分配并指出任何无效的内存操作。 I bet your Linux distro has a pre-compiled package for it. 我打赌你的Linux发行版有一个预编译的包。

This here is causing the issue 这是造成这个问题的原因

  delete[] m_xDataOut; 
  delete[] m_yDataOut;    

you have not initialized the pointers in your constructor 您尚未在构造函数中初始化指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM