簡體   English   中英

我要釋放內存兩次-C ++

[英]I'm freeing memory twice - C++

我已經完成了該程序,在這里檢查“日期”類是否正確。 問題是,當我運行測試程序時,它返回以下錯誤:

  • `./bin/test'中的錯誤:兩次釋放或損壞(快速更新):0x00000000019c07c0 *

讀取此類的工作,並存儲一個“日期”(一年)和一些事件(以字符串數組分配)。 例如,此類的對象將是:1998 EVENT1 EVENT2 EVENT3。

操作員>>讀取下一個格式:1908#Fantasmagorie#馴悍記#The Thieving Hand#Guise遇刺公爵#A前往海邊

好吧,我的問題是我要刪除兩次指針或兩次釋放一些內存,我嘗試了很多事情,但是我不知道如何解決(如您在我的代碼上所看到的,我已經嘗試過刪除它們時將所有指針都設置為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

我為我的英語感到抱歉!!! :,(

由於代碼中沒有賦值重載,因此該行

    d=d1;

d1所有成員將按值復制到新對象d 因此,將有兩個對象date副本,其成員str具有相同的參考值。 這兩個最終將超出范圍,並且都將被破壞。 第一個將釋放分配的內存,而另一個將嘗試釋放相同的引用,這就是為什么會出現錯誤。

您需要一個副本分配運算符:

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;
}

提供移動構造函數也可能會很不錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM