2014-05-04 50 views
-3

你好我想這個字符指針釋放內存,但因爲它是作爲名稱初始化我不能刪除/釋放它。我該如何處理這種情況?我的頭文件和實現文件如下所示。問題,在正確釋放內存

/// Header file. 

#ifndef __DAY_H__ 
#define __DAY_H__ 


class day { 
    private: 
     char* name; 
     int nClasses; 
     bool status; //working day or a holiday 

    public: 
     day(); 
     day(char * name, int place, bool status); 
     day(const day&); 
     //operator=(const day&); 
     ~day(); 

     char * getName() const; 
     int getClasses() const; 
     bool getStatus() const; 

     void setName (char * name); 
     void setClasses (int classes); 
     void setStatus (bool status); 
}; 


#endif 


/// .cpp file 
#include <iostream> 
#include "day.hpp" 
#include <string.h> 

day::day() 
{ 
    name = new char[10]; 
    name = "Monday"; 
    nClasses = 1; 
    status = true; 
} 

day::day(char * _name, int _classes, bool _status) 
{ 
    name = new char[10]; 
    strncpy(name, _name, 10); 
    nClasses = _classes; 
    status = _status; 
} 

day::day(const day& _myday) 
{ 
    name = new char[10]; 
    name = _myday.name; 
    nClasses = _myday.nClasses; 
    status = _myday.status; 
} 

char* 
day::getName() const 
{ 
    return name; 
} 

int 
day::getClasses() const 
{ 
    return nClasses; 
} 

bool 
day::getStatus() const 
{ 
    return status; 
} 

void 
day::setName(char * _name) 
{ 
    name = _name; 
} 

void 
day::setClasses(int _classes) 
{ 
    nClasses = _classes; 
} 

void 
day::setStatus(bool _status) 
{ 
    status = _status; 
} 

day::~day() 
{ 
    if (name != 0) { 
     std::cout << "Deleting name" << std::endl; 
     delete name; 
    } 
} 

感謝您的幫助。

+1

使用**的std :: string **,忘記所有這些問題! – Mat

+1

如果你只是使用'std :: string',你意識到你可以避免所有這些痛苦? –

+1

請刪除所有不相關的代碼。您發佈的大部分內容與您所報告的問題無關。另外,如果你不能使用'std :: string',你應該在問題中提到它。 – juanchopanza

回答

0

如果這不是一項家庭作業練習,請在那裏停下來,將char*替換爲std::string,並解決您的問題。

(另外,你可以刪除你的析構函數和拷貝構造函數,編譯器生成的人就足夠了。)


如果這是在手動內存管理的鍛鍊,那麼你需要解決幾個方面。

你必須在兩個地方這種模式:

char *var = new char[N]; 
var = something_else; 

這是內存泄漏。指針new給你在第二個語句中被別的東西替換。你沒有指向新分配塊的另一個指針,所以它已經泄漏。

更重要的是,在默認的構造函數的第二次轉讓的形式爲:

var = "string literal"; 

不允許你刪除一個字符串,它具有程序的生命週期。所以你最終在泄漏內存的情況下,你不能判斷你是否必須刪除或不在你的析構函數中。

爲了解決這個問題,你必須做一個分配(如有必要),然後從任何來源你得到副本。這也有利於不直接存儲你已經傳遞的指針,如果調用者決定釋放它自己,這將導致其他錯誤。所以,即使源是一個字符串文字:

var = new char[N]; 
strncpy(var, source, N); 
var[N-1] = 0; // check the docs for strncpy very carefully 

一旦你已經修復了,你需要通過Rule of Three遵守,你真的需要一個拷貝賦值運算符。它需要適當地處理自我分配。

然後,你必須解決您的析構函數了。您分配namenew[]。您需要必須取消分配delete[]。這兩個手牽手。 (測試爲name != 0是沒有必要的,deletedelete[]手柄零點很好 - 即交給一個空指針時,他們什麼都不做)。

而且它是瞭解std::shared_ptrstd::unique_ptr的好時機。在大多數情況下,應避免使用原始的newdelete

+0

謝謝你們。我解決了它。這不是一項家庭作業練習,但我正在學習C++並閱讀Scott Mayers,所以試圖單獨嘗試一些東西。如果有很好的C++練習,請與我分享。我可以編程我的邏輯,但想在C++的設計和設施方面做得更好。繼續前進,我會嘗試僅發佈相關代碼。再次感謝。 – digitalRevolution

+0

確保你關注最近的一本書。基本原理仍然適用於較舊的材料,但在過去的幾年中,情況發生了很大變化,尤其是,在C++ 11之後。在大多數正常的C++程序中,像上面這樣的手動內存管理是不必要的(特別是不適用於'char *') – Mat