我释放了两次内存 - C ++

时间:2017-10-28 18:55:04

标签: c++

我做了这个程序,检查我的'日期'类是否正确。问题是,当我运行我的测试程序时,它返回了我的以下错误:

  • `./bin/test'出错:double free或corruption(fasttop):0x00000000019c07c0 *

读取此类的作业并存储“日期”(一年)和一些事件(以字符串数组分配)。例如,此类的对象将是:1998 EVENT1 EVENT2 EVENT3。

运营商>>阅读下一个格式:1908#Fantasmagorie#驯悍记#盗贼之手#暗杀公爵的暗杀#A访问海边

好吧,我的问题是我正在删除一些指针两次或释放一些memmory两次,我已经尝试了很多东西,但我不知道如何解决它(正如你在我的代码上看到的,我有我删除它们时已经尝试将所有指针设置为0。): 日期类.h

#ifndef _date_HISTORICA_
#define _date_HISTORICA_

#include <iostream>
#include <string>
#include <cassert>

using namespace std;

class date{
private:
    int year;
    int eventsNum;
    int reserved;
    string * str;
    void resize(int r);
public:
    date();
    //date(int a, string *s, int n);
    date(const date& d);
    ~date();
    int getAge();
    void addEvent(string& s);
    friend ostream& operator<<(ostream& os, const date& d);
    friend istream& operator>>(istream& is, date& d);
};



#endif

日期类代码:

#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<date.h>

using namespace std;

void date::resize(int r)
{
    assert(r>=0);
    if(r!=this->reserved)
    {
     if(r!=0)
     {
        string * aux = new string[r];
        if(this->reserved>0)
        {
            int min=this->reserved<r?this->reserved:r;
            for(int i=0; i<min; i++)
                aux[i]=this->str[i];
            delete[] this->str;
            this->str=NULL;
        }
        this->str=aux;
        this->reserved=r;
        if(this->reserved<this->eventsNum)
            this->eventsNum=this->reserved;
     } else
     {
        if(this->reserved>0)
        {
            delete[] this->str;
            this->str=NULL;
        }
        this->year=0;
        this->eventsNum=0;
        this->reserved=0;
     }
    }
}

date::date() : year(0), eventsNum(0), reserved(0), str(0){}

date::date(const date& d)
{
    this->year=d.year;
    this->eventsNum=d.eventsNum;
    this->reserved=d.reserved;
    this->str=new string[this->reserved];
    for(int i=0; i<this->eventsNum; i++)
        this->str[i]=d.str[i];
}

date::~date()
{
    this->year=0;
    this->eventsNum=0;
    this->reserved=0;
    if(this->str)
    delete[] this->str;
    this->str=NULL;
}

int date::getAge(){return this->year;}

ostream& operator<<(ostream& os, const date& d)
{
    os << d.year;
    for(int i=0; i<d.eventsNum; i++)
        os << '#' << d.str[i];
    os << endl;
    return os;
}

void date::addEvent(string& s){
    if (this->eventsNum == this->reserved){
       if (this->eventsNum==0)
          resize(1);
       else
          resize(2*this->reserved);
    }
    this->str[eventsNum]=s;
    eventsNum++;
 }

istream& operator>>(istream& is, date& d)
{
    string line; char c;
    is >> d.year >> c;
    getline(is, line);

    int n=1;
    for(int i=0; i<line.length(); i++)
        if(line[i]=='#')
            n++;

    d.eventsNum=n;
    d.reserved=d.eventsNum;
    delete[] d.str;
    d.str=NULL;
    d.str=new string[n];

    stringstream ss(line);

    for(int i=0; i<n; i++)
        getline(ss, d.str[i], '#');
    return is;
}

测试程序类:

#include<iostream>
#include<fstream>
#include<cronologia.h>
#include<date.h>

using namespace std;

int main(int argc, char * argv[]){
    cout <<  "STATE: IN PROGRESS" << endl;
    cout << "TEST: (2)" << endl;
    date d;

    ifstream f("./data/name.txt");

    while(f >> d)
    {
        cout << d;
    }
    date d1;
    cin >> d1;
    d=d1;
    cout << d << endl;


}

示例文件(应该由日期字符读取):

1900#Sherlock Holmes Baffled#The Enchanted Drawing
1901#Star Theatre#Scrooge, or, Marley's Ghost
1902#A Trip to the Moon
1903#The Great Train Robbery#Life of an American Fireman
1904#The Impossible Voyage
1905#Adventures of Sherlock Holmes; or, Held for Ransom
1906#The Story of the Kelly Gang#Humorous Phases of Funny Faces#Dream of a Rarebit Fiend
1907#Ben Hur#L'Enfant prodigue
1908#Fantasmagorie#The Taming of the Shrew#The Thieving Hand#The Assassination of the Duke of Guise#A Visit to the Seaside

我很抱歉我的英文! :,(

2 个答案:

答案 0 :(得分:3)

由于代码中没有赋值重载,行

    d=d1;

d1的所有成员都将按值复制到新对象d。因此,对象date将有两个副本,它们在其成员str中具有相同的参考值。这两个最终将超出范围,两者都将被破坏。第一个将释放分配的内存,而另一个将尝试释放相同的引用,这就是你得到错误的原因。

答案 1 :(得分:-1)

您需要一个复制赋值运算符:

void swap(date& other) 
{
    using std::swap;
    swap(year, other.year);
    swap(eventsNum, other.eventsNum);
    swap(reserved, other.reserved);
    swap(str, other.str);
}

date::date(const date& d) : year(other.year), eventsNum(other.eventsNum), reserved(other.reserved), str(new string[other.reserved])
{
    for(int i = 0; i < this->eventsNum; i++)
        this->str[i] = d.str[i];
}

date& date::operator = (const date& d)
{
    swap(*this, d);
    return *this;
}

也可以提供移动构造函数。