2016-03-28 56 views
0

下面的代碼應該實現我自己的字符串類。類似於如果你想創建這樣的String s = "Hi";。我在銷燬時遇到錯誤,並獲取到delete[] data的部分。是說當我離開堆緩衝區時,我在寫信。這些不是cstrings,所以在我的字符串末尾沒有空字符。刪除字符指針越來越堆錯誤

這裏是我的轉換/默認構造函數:

String346::String346(const char * oldString) : data(NULL), size(static_cast<unsigned int>(strlen(oldString))){ 
    data = new(std::nothrow) char[size]; 
    for (unsigned int i = 0; i <= getSize(); i++){ 
     data[i] = oldString[i]; 
    } 
} 

由於這些功能需要支持的功能鏈接,我要把我的,涉及到我的問題,這兩個功能之一,如果一個String346對象傳遞或者一個char *中傳遞

串聯其中char *在傳遞函數:

String346 & String346::concat(const char * catString) { 
    String346 newCatString(catString); 
    concat(newCatString); 
    return (*this); 
} 

級聯功能,其中String346對象傳入:

String346 & String346::concat(const String346 & catString) { 
     String346 tempData(data); 
     size = tempData.getSize() + catString.getSize(); 
     destroy(); 
     data = new (std::nothrow) char[size]; 
     if (data == NULL){ 
      std::cout << "Not enough space to concatinate this string." << std::endl; 
     } 
     else{ 
      unsigned int index = 0; 
      for (unsigned int i = 0; i < getSize(); i++){ 
       if (i < tempData.getSize()){ 
        data[i] = tempData.data[i]; 
       } 
       else{ 
        data[i] = catString.data[index]; 
        index++; 
       } 
      }  
     } 
     return (*this); 
    } 

我破壞功能,做所有的工作對象的破壞也很簡單。它包含以下三行:

delete[] data; 
    data = NULL; 
    size = 0; 
    return; 

回答

1

你的構造分配char陣列含有size元素。

然後,您的構造函數似乎將size+1字符複製到數組(我假設getSize()返回size)。

因此,構造函數代碼在數組的末尾運行,並且破壞了分配數組末尾的一個字節。

P.S. static_cast不是必需的,只會使代碼更加混淆。

0

第一行中的concat方法:

String346 tempData(data); 

通行證一個char *你的構造函數不爲NULL終止,所以調用strlen將越過字符串的結尾。

接下來的兩行也不起作用:

size = tempData.getSize() + catString.getSize(); 
    destroy(); 

destroysize回到零,這意味着你的方法的其餘部分將不會做任何事情。

您應該嘗試通過調試器並單步執行此操作 - 然後您可以在每個步驟檢查變量的值,並確保您的程序正在按照您的期望執行。另外,如果你有一個在析構函數中被釋放的成員變量,你應該查看「三個規則」或「五個規則」,以確保事情不會被釋放兩次。