2014-04-03 27 views
1

我正在製作一個簡單的程序,它允許我通過向公用成員函數發送一個字符數組來設置對象的名稱,該公共成員函數隨後更改名爲name的私有變量。然後我告訴我的班級吐出名稱變量,以便我可以看到它是否正常工作 - 但是我的輸出大部分出現亂碼。顯示來自對象的字符數組

即我輸入

「蘋果」

和輸出成爲

「AAAAA╠╠╠╠Apple」

我注意到,當我改變單詞時,重複字符的數量模仿了數字這個詞中的字符 - 但我似乎無法弄清楚我在哪裏搞亂了我的程序。這是我的代碼:

*注意:下面的代碼現在按預期工作。

#include <iostream> 
    #include <cstring> 

    using namespace std; 

    class Item{ 

     public: 
    ~Item() { delete [] name; } 

    char *setName(char * inputName) 
    { 
     name = new char[strlen(inputName)+1]; 

     int n = 0; 
     for(n = 0; n<strlen(inputName); n++) 
      name[n] = inputName[n]; 

     name[n] = '\0'; 

      return name; 
    } 

     private: 
      char *name; 
}; 


    int main() 
    { 
     char objectname[] = "Apple"; 

     Item Apple; 
     cout << Apple.setName(objectname); 

     int input; 
     cin >> input; //pause program 
    } 
+1

你永遠不會爲'name'分配內存。另外,'char name []'應該是'char * name',因爲'char name []'是一個零大小的數組,在C++中是非法的。 – 0x499602D2

+2

簡化你的生活,改爲使用'std :: string'。 –

+0

@ThomasMathews我試圖避免在這個程序中使用字符串類。 – Durgal

回答

2

正如我在我的評論中所說的,你永遠不會爲name分配內存。當使用name[n]時,您將被解除引用不屬於您的地址。這會導致程序中出現Undefined Behavior,這意味着任何可能發生的不符合程序邏輯的事情。它甚至可以編譯得很好,但你不能依賴它。

無論如何,您需要爲name分配內存。但爲此,您需要知道分配內存的大小。我們不知道內存的大小(它可以是發送到setName的任意字符串)。因此name必須是一個指針:

char* name; 

然後我們可以給它分配內存。順便說一句,char name[]是一個零大小的數組,這在C++中是非法的。

setName的內部,您需要獲取發送給它的字符串的大小。 strlen適合這份工作,但您還需要爲空終止符('\0')騰出空間。這是字符被追加到每個字符串的末尾,如果您不添加它並稍後嘗試打印namestd::cout將不知道在哪裏停止打印每個字符(這也是未定義的行爲)。

setName裏面,這應該是動態存儲器的分配到name

name = new char[strlen(inputName) + 1]; 

含義:(在inputName +空終止字符數)。注意:strlen不計算空終止符。

現在,設置空終止符,你只需做以下for()循環:

name[n] = '\0'; 

而且,當您正在使用的內存name完成後,你必須將其刪除。你這樣做,使用delete[]

delete[] name; 

推薦的替代方案是使用std::string通過自身管理內存的標準C++字符串類。

+0

謝謝!我開始得到結果 - 我已經更新了程序,但仍然出現錯誤。不知道我在哪搞亂...... – Durgal

+0

@Durgal你能分享一個鏈接到更新的代碼[這裏](http://ideone.com)。另外,告訴我什麼錯誤是太請了。 – 0x499602D2

+0

@Durgal在這個範圍內沒有聲明'x'消息通常意味着編譯器無法找到名稱爲'x'的聲明。在這種情況下,我們知道'strlen'是一個標準的C函數,所以通常的解釋是你沒有包含合適的文件來使用該函數。當我查找'strlen'的文檔時,我發現它在頭文件''中定義。所以你所需要做的就是在你的程序中#include 。 – 0x499602D2