2016-11-16 94 views
1

我試圖創建一個數組,每個對象在數組中應該有名稱模型(i)其中是索引,我這樣做,使他們將按降序排列的名稱Model5,Model4。 ..我試圖做到這一點使用char [],但由於某種原因在我的代碼中使用for循環內的strcat使我卡住在一個無限循環,第二點,如果有人可以幫助轉換索引的方式我可以連接名稱並賦予構造函數。C++ strcat創建無限循環

#include <iostream> 
#include <stdio.h> 
#include <string> 

using namespace std; 

class CARRO { 
    public: 
     CARRO() {}; 
     CARRO(char *modelo, unsigned ano); 
     char* getModelo(); 
     unsigned getAno(); 
    private: 
     char modelo[100]; 
     unsigned ano; 
}; 

void swap(int *p, int *q); 
int partition(int *v, int start, int end); 
int randomizedPartition(int *v, int start, int end); 
void qsHelper(int *v, int start, int end); 
void quickSort(int *v, int len); 
void printList(CARRO *carros, unsigned len); 

int main(int argc, char const *argv[]) { 

    CARRO carros[5]; 
    unsigned len = sizeof(carros)/sizeof(CARRO); 

    for (int i = 0; i < len; ++i) { 
     char modelo[] = "Modelo"; 
     char id[] = "I"; 
     strcat(modelo, id); 
     unsigned ano = 1000 * (i+1); 
     carros[i] = CARRO(modelo, ano); 
     cout << carros[i].getModelo() << endl; 
    } 

    //printList(carros, len); 

    return 0; 
} 

CARRO::CARRO(char *modelo, unsigned ano) { 
    strcpy(this->modelo, modelo); 
    this->ano = ano; 
} 

如果我刪除行:

strcat(modelo, id); 

循環工作正常。我只是不明白爲什麼strcat會以某種方式產生一個無限循環。輸出是這樣的:(與線的strcat)

ModeloI 
ModeloI 
ModeloI 
ModeloI 
ModeloI 
ModeloI 
ModeloI 
ModeloI 
ModeloI 
ModeloI 
^CModeloI 
+1

如果您使用C++,你應該使用'的std :: string'和相關方法而不是C的'的strcat '與字符數組 –

+4

'm odelo'只能創建到足以容納您初始化的單詞。如果使用'std :: strcat'使內容更長,則您正在寫入數組邊界之外導致未定義的行爲。 – Galik

+0

可能重複的[我只是無法找出strcat](http://stackoverflow.com/questions/4707900/i-just-cant-figure-out-strcat) –

回答

1

環路工作正常。我只是不明白爲什麼strcat會以某種方式產生一個無限循環。輸出是這樣的:(用線strcat)

該循環工作正常!你在摧毀記憶。讓我們把一些箱子代表堆棧可能你的程序中可以看出(假設環路剛剛去各地1):

+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
| char modelo[7]       | int i     | unsigned len   | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
| 'M' | 'o' | 'd' | 'e' | 'l' | 'o' | 0 | 1 | 0 | 0 | 0 | 5 | 0 | 0 | 0 | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 

所以,當你這樣做:

strcat(modelo, id); 

你最終會得到一個字節的緩衝區溢出。在我的具體的例子,這將覆蓋變量i的第一個字節,從而使你的循環無限期地持續下去:

+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
| char modelo[7]       | int i     | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
| 'M' | 'o' | 'd' | 'e' | 'l' | 'o' | 'I' | 0 | 0 | 0 | 0 | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
              ^^^^^ 
              Nul-terminator written 

當然,我已經完全奠定了你的籌碼是這樣的一個例子。你的編譯器可能不會像這樣保持堆棧在一起。有可能是您的陣列後,額外的填充,它可能可能剛剛發生「工作」。變量i可能被保存在寄存器中,永遠不會在內存中,或者編譯器可能已完全展開循環。你的架構可能是是big-endian(而不像我的例子中的little-endian)。

問題是,最終的行爲是完全未定義的。即使您的計算機上獲得一致的結果,我們也無法查看此代碼並說出會發生什麼。

因此,要解決這個問題,你可以簡單地modelo足夠大的存儲字符串"ModeloI"包括終止,這意味着使它大到足以存儲8個字節,而不是7:

char modelo[8] = "Modelo"; 

,那麼你就已定義的行爲,不管堆棧是否佈局爲低於或其他任何方式:

+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
| char modelo[8]        | int i     | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
| 'M' | 'o' | 'd' | 'e' | 'l' | 'o' | 'I' | 0 | 1 | 0 | 0 | 0 | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ 
+0

非常感謝你解釋@paddy,我決定使用std :: string,所以現在問題已經解決了!但是非常感謝,現在我將在使用char []時知道。 –