2011-12-23 50 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; 
} 
相关问题