2014-12-07 74 views
0

我在練習C++。在C++中爲分配內存錯誤分配異常*

我在兩個版本中實現了String類。在第一個版本中,文本保存在一個數組中。在第二個版本中,文本保存在動態分配內存中。第一個版本繼承 。

第一個版本工作正常。 在第二個版本中,在concat函數的第一行中,我得到一個錯誤的分配異常。

這是代碼:

 #include<iostream> 
    #include<string> 
    using namespace std; 

    class String{ 

    protected: 
     enum{SIZE=256}; 
     void setLen(const int length) 
     { 
      m_len = length; 
     } 
    private: 
     int m_len; 
     char m_text [SIZE]; 

    public: 

     String() 
     { 
      m_len = 0; 
      strcpy_s (m_text, 1, ""); 
     } 
     String(const char* text) 
     { 
      m_len = strlen(text); 
      strcpy_s (m_text, strlen(text) + 1, text); 
     } 
     const char* get() const 
     { 
      return m_text; 
     } 
     virtual void set(char* text) 
     { 
      strcpy_s (m_text, strlen(text) + 1, text); 
     } 
     int getLen() const 
     { 
      return m_len; 
     } 
     virtual void concat(const String &s) 
     { 
      strcat_s(m_text, strlen(m_text) + strlen(s.get()) + 1, s.m_text); 
     } 
     bool equal(const String &s)const 
     { 
      return strcmp(s.m_text, m_text); 
     } 
     bool operator ==(const String &s)const 
     { 
      return strcmp(s.m_text, m_text); 
     } 
     virtual void print()const 
     { 
      cout<<m_text; 
     } 


    }; 

    class PointString :public String { 
     char* m_text; 
    public: 
     PointString() 
     { 
      setLen(0); 
      m_text = new char[1]; 
      strcpy_s(m_text, 1,""); 
     } 
     PointString(const char* text) 
     { 
      setLen(strlen(text)); 
      m_text = new char[strlen(text)+1]; 
      strcpy_s(m_text, strlen(text)+1 ,text); 
     } 
     void set(char* text) 
     { 
      delete [] m_text; 
      setLen(strlen(text)); 
      m_text = new char[strlen(text)+1]; 
     } 
     void concat(const String &s) 
     { 
      char *temp = new char[strlen(m_text) + strlen(s.get())]; 
      strcpy_s(temp, SIZE, m_text); 
      strcat_s(m_text,strlen(m_text) + strlen(s.get()) + 1, s.get()); 
      delete [] m_text; 
      m_text = temp; 
     } 
     void print()const 
     { 
      cout<<m_text<<endl; 
     } 
    }; 

void main() 
{ 
    PointString str("1234"); 
    str.print(); 
    str.concat("8901"); 
    str.print(); 
    system("pause"); 
} 
+3

您將'm_text'初始化爲'new char []',但是您不一定會在數組中放入''\ 0'(取決於使用哪個構造函數)。如果沒有空終止符,'strlen'的行爲是不確定的。 – dlf 2014-12-07 01:40:58

+0

我還必須指出讓'PointerString'從'String'繼承字符數組的設計問題。 – 2014-12-07 01:42:15

+0

不相關,但'strcpy_s'是微軟的,而不是標準的C++ – vsoftco 2014-12-07 01:42:58

回答

1

問題是這在您的通話concat

char *temp = new char[strlen(m_text) + strlen(s.get())]; // 1 
    strcpy_s(temp, SIZE, m_text); 
    strcat_s(m_text, strlen(m_text) + strlen(s.get()) + 1, s.get()); // 2 
    delete[] m_text; 
    m_text = temp; 

對於問題// 1,你沒有爲字符串分配足夠的空間。您忘記了終止空條目。

對於問題// 2,在連接到m_text之前,它的大小正確。

使用標準的字符串函數,以下原因改變沒有任何問題:

char *temp = new char[strlen(m_text) + strlen(s.get()) + 1]; 
    strcpy(temp, m_text); 
    strcat(temp, s.get()); 
    delete[] m_text; 
    m_text = temp; 

使用Microsoft安全字符串函數,你應該保存新的字符串的長度在一個變量並在每個呼叫時使用。指定SIZE似乎不正確。下面是我的什麼作品:

void concat(const String &s) 
{ 
    size_t sz = strlen(m_text) + strlen(s.get()) + 1; 
    char *temp = new char[sz]; 
    strcpy_s(temp, sz, m_text); 
    strcat_s(temp, sz, s.get()); 
    delete[] m_text; 
    m_text = temp; 
} 

有你的代碼的其他問題。一個是缺少析構函數,因此無論何時創建PointString,都會發生內存泄漏。另一個問題是,由於缺少用戶定義的複製構造函數和賦值運算符,因此將PointString複製並分配給另一個PointString將無法​​正常工作。

請仔細閱讀上述主題,因爲字符串類不能複製自己幾乎不值得使用(如果您打算使用它),由於內存泄漏,根本無法使用目前(沒有析構函數)。

如果您將自己從「作業」階段中刪除,std::string類將完成您現在正在執行的所有工作,除了更安全和高效。