2012-09-06 36 views
0

這裏是我的代碼:C++:爲什麼我得到分段錯誤?

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


using namespace std; 

struct Computer 
{ 
    char * model; 
    char * assembler; 
    int processorInt; 
}; 

int main() 
{ 
    Computer comp; 
    char* model; 
    char* assembler; 
    int processorInt; 

    cin>>model; 
    cin>>assembler; 
    cin>>processor int; 

    comp.model = model; 
    comp.assembler = assembler; 
    comp.processorInt = processorInt; 

    return 0; 
} 

//如果我這樣做,它的工作原理,但如果我用另一種方式做,這讓段錯誤

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


using namespace std; 

struct Computer 
{ 
    char * model; 
    char * assembler; 
    int processorInt; 
}; 

void setValues() 
{ 
    Computer comp; 
    char* model; 
    char* assembler; 
    int processorInt; 

    cin>>model; 
    cin>>assembler; 
    cin>>processor int; 

    comp.model = model; 
    comp.assembler = assembler; 
    comp.processorInt = processorInt; 
} 

int main() 
{ 
    setValues(); 

    return 0; 
} 

那麼是什麼原因呢?

我的目標是創建結構,其中我可以節省約每一個「電腦」的一些信息,然後做一個可能性編輯任何結構,然後通過procesorInt整個數組排序的數組。但我甚至無法創建一個正常的可編輯結構。

+5

你輸入一個未分配,未初始化的指針。你需要使它指向一些預先分配的內存,爲它分配內存(涉及第一部分),或者最重要的是使用'std :: string'。 – chris

+1

什麼是'cin >>處理器int;'? –

+6

第一個工作,因爲你不走運。第二個不行,因爲你很幸運。 –

回答

2

這兩個版本都不能正常工作,您正嘗試將數據讀入未初始化的指針。只要聲明例如char* model;給你一個未初始化的指針:它可以指向內存中的任何點。當您嘗試使用cin >>在該位置存儲字符串時,您將寫入不屬於您的內存。這可能會出現段錯誤,或者它可能看起來有效。

剛剛宣佈char*不給你的字符串空間:如果您使用的是標準的C字符串,那麼你就需要給他們一些數據:使一個固定大小的你char指針數組,或者使用malloc來分配一個字符串緩衝區:

char model[MAX_STRING_LENGTH]; 

或者使用malloc,但要注意,你需要free此內存後:

char *model = malloc(MAX_STRING_LENGTH); 

現在,如果你要使用標準的C字符串和cin在一起,你根本不應該使用>>:沒有辦法限制輸入大小。請使用cin.getlineMAX_STRING_LENGTH作爲限制(有關詳細信息,請參閱文檔中的示例)。

但絕對寧願使用std::string來代替:如果你這樣做,那麼你就不需要爲自己提供空間來處理字符串,而且你的代碼根本不需要改變很多。

+0

感謝您解釋,在c#後這個主題對我來說很奇怪 –

+0

您無法從輸入安全地讀取到固定大小的緩衝區;沒有辦法來防止超限。 'std :: string'是這裏唯一明智的選擇。 –

+0

@MikeSeymour非常感謝Mike,這非常重要,我已經多加了一點。 – pb2q

5

您正在閱讀到不隨地指着char指針。沒有空間來存儲讀取的字符。

容易得多是使用std::string,beause將automayically調整自身,以穩住老從輸入的字符。

Computer comp; 
std::string model; 
std::string assembler; 
int processorInt; 

cin>>model; 
cin>>assembler; 
cin>>processorInt; 
+0

非常感謝,但練習的一部分是使用類C字符串 –

+0

@RomaBugaian,然後我更喜歡'std :: unique_ptr '。這樣你就可以減少一個擔心的問題。但是,根據C字符串是定義爲字符數組還是必須自己管理的指針,您可能必須選擇比智能指針更差的選項。 – chris

+0

@RomaBugaian:那麼我希望這個練習的重點是教你緩衝區溢出的危險和消毒輸入的重要性。您無法安全地將C風格的字符串與C++風格的格式化輸入結合使用。 –

相關問題