2011-12-23 95 views
2

我正在嘗試寫我自己的字符串類(所以我可以瞭解更多),同時這樣做我注意到我遇到了如何刪除char數據的問題當程序關閉字符串的析構函數將被調用,就會出現一堆錯誤的刪除數據爲什麼我在刪除char *時出現內存異常?

#include <string.h> 

template<typename T> 
class String 
{ 
protected: 
    T* mData; 

public: 
    String(const T* data); 
    ~String(); 
}; 

template<typename T> 
String<T>::String(const T* data) 
{ 
    if(data != NULL) 
    { 
     mData = new T[strlen(data)]; 
     strcpy(mData, data); 
    } 
} 

template<typename T> 
String<T>::~String() 
{ 
    if(mData != NULL) 
    { 
     delete [] mData; 
     mData = 0; 
    } 
} 

int main(void) 
{ 
    String<char> Test("Test"); 

    return(0); 
} 
+1

在刪除前不需要測試NULL(或將值設置爲0後)。 – 2011-12-23 19:54:26

+1

你需要遵守三條規則。否則,你會在第一個副本之後崩潰。 – 2011-12-23 19:55:12

+0

你是對的,我違反了三條規則(我想要一個簡單的測試用例) – judeclarke 2011-12-23 20:03:27

回答

5
mData = new T[strlen(data)]; 
     strcpy(mData, data); 

您分配一個項目太少,strcpy的複製NUL終止字節,以及字符串

+0

就是這樣,我完全忘了這一點。感謝您的幫助。 – judeclarke 2011-12-23 20:04:18

0

你應該使用「memcpy」和「memset」函數而不是像strcp那樣的函數Y:

http://www.cplusplus.com/reference/clibrary/cstring/memcpy/

+0

這是爲什麼呢? – judeclarke 2011-12-24 08:32:12

+0

通過使用'memcpy'函數,您正在處理快速的內存塊。另外'strcpy'是不安全的,因爲它可能導致溢出,就像你的情況一樣,'strlcpy'功能是安全的。當你使用內存塊功能時,你有完整的內存控制。我個人更喜歡兩個字符串clasess一個用於char類型,另一個用於wchar_t類型,它們都從同一個通用抽象類(接口)繼承,而不是使用模板(泛型)。 – ArBR 2012-01-10 02:57:07

0

你必須小心操作新在構造函數拋出異常。如果發生這種情況,你必須確保你的數據指針初始化爲nullptr,otherwize,析構函數將被調用並嘗試刪除一些隨機地址。

#include <cstring> 

template<typename T> 
class string { 
    protected: 
     T * data_; 
    public: 
     string(T const * data); 
     ~string(); 
}; 

template<typename T> 
string<T>::string(T const * data) 
try { 
    if(!data) data_ = 0; 
    else { 
     data_ = new T[std::strlen(data) + 1]; 
     std::strcpy(data_, data); 
    } 
} catch(...) { 
    data_ = 0; 
} 

template<typename T> 
string<T>::~string() { 
    delete[] data_; 
} 

int main() { 
    string<char> test("test"); 
    return 0; 
} 
相關問題