2012-11-27 135 views
0

我有這個代碼的問題。我正在使用gcc編譯器,當我編譯並執行此代碼時,我正在收到seg錯誤。我只是分配兩個變量,name_1作爲指針,name_2作爲字符串。當我試圖爲兩個值提供字符串輸入時,我正在收到seg故障。此seg錯誤總是與我正在使用的指針變量相關聯。字符串 - 分段錯誤

下面我提供了代碼和錯誤的截圖。

#include <stdio.h> 

int main() 
{ 
char *name_1 ; 
char name_2[10] ; 

/*  Getting 2 strings as an input from the user 
     and is stored in the pointer variable name_1 and name_2*/ 
scanf("%s",name_1) ; 
scanf("%s",name_2) ; 

/*  Printing the values of the varibales 
     name_1 and name_2 in string format  */ 
printf("\n%s",name_1) ; 
printf("\n%s",name_2) ; 

printf("\n\n") ; 
return 0 ; 
} 

請幫我看看這段代碼。

Seg fault

+1

這是不是一個好主意,改變問題,以使答案已經提供無效。保留原文(也許作爲評論)並顯示更正是可以的;只是糾正代碼並使您得到的答案無效才行。 –

+2

請注意,如果您使用的是GCC並且使用'-Wall'編譯,那麼您會收到編譯器發出的有關您的錯誤的警告。如果你使用的是GCC,確保你使用(至少)'-Wall'進行編譯。如果您使用其他編譯器,那麼瞭解如何打開更多警告。 –

+0

先生, 現在我實際上有更多的疑惑。每當我聲明一個變量,它是不是分配一個空間? –

回答

0
char *name_1 ; 
... 
scanf("%s",&name_1) ; 

name_1是一個懸擺指針,你要使用它,這是不正確。

+0

它是一個懸掛指針還是一個未初始化的指針?不是懸掛的指針,它曾經是有效的,但不再有效(指向已退出的函數中的局部變量,或指向已被釋放的動態分配內存)? –

+0

我認爲在這種情況下更準確的名稱是[野指針](http://en.wikipedia.org/wiki/Dangling_pointer#Cause_of_wild_pointers),儘管人們似乎在這種情況下使用了懸掛指針這個詞,即使它不是嚴格準確。 –

3

char *name_1;,是一個指針。最初,它指向一些隨機垃圾。然後,您要求scanf將隨機垃圾地址name_1恰好指向程序啓動時的字符串;這是未定義的行爲。一致的C實現可以讓這個程序按預期的方式工作,如果需要的話,只在星期二。 :)

如果你要傳遞一個指針,你必須確保它首先指向一個有效的緩衝區。

此外,您在呼叫scanf - name_1已經是一個指針時有間接違反的程度。您不想將指針傳遞給指向scanf的指針;只是一個指針。

+0

所以。如果name_1指針最初指向NULL,然後在scanf中使用,這會工作嗎? –

+0

@Rajan:編號'scanf'永遠不會爲你分配緩衝區。這是'scanf'在生產代碼中永遠不能安全使用的原因之一;因爲分配正確大小的緩衝區是不可能的。 –

+0

否;如果'char * name_1 = NULL;'會傳遞給'scanf()',它會崩潰。 –

2

問題的原始版本包含:

char *name_1; 
... 
scanf("%s", &name_1); 

的問題已經被修改爲包含:

char *name_1; 
... 
scanf("%s", name_1); 

您還沒有分配的任何空間name_1指向。您還通過了char **(即&name_1)至scanf(),其格式爲%s,預計該格式爲char *

可能的解決辦法:

int main(void) 
{ 
    char name_1[20]; 
    char name_2[10]; 

    scanf("%s", name_1); 
    scanf("%s", name_2); 

另一種可能的解決辦法:

int main(void) 
{ 
    char name_0[20]; 
    char *name_1 = name_0; 
    char name_2[20]; 

    scanf("%s", name_1); 
    scanf("%s", name_2); 
+0

先生, 這樣做有什麼用?我要指出的是,一個數組是一個更好的主意。但是我爲數組變量寫了另外20個字節,或者爲指針變量浪費了8個字節。 –

+0

您必須設置'name_1',以便指向某個有效的地方以確保您的程序不會崩潰(或至少減少崩潰的機率 - 您需要將'%s'格式修改爲'%19s'或' %9s'相當安全)。你必須有'scanf()'空間來存儲它讀取的數據。如果這是一個兆字節的空間,你會有理由持懷疑態度。很少有8個字節或20個字節有所不同的機器。你不是在浪費空間(儘管第二個代碼片段肯定會使用更多);你正在使用它。我會選擇第一個選項,但這取決於以後如何使用name_1。 –

0

你的指針char *name_1應該指向的東西。 作爲一項規則遵循

Declaring a pointer variable does not create the type of variable, 
it points at. It creates a pointer variable. So in case you are pointing 
to a string buffer you need to specify the character array and a buffer 
pointer and point to the address of the character array. 

推薦變化:

  • 你可以有你char *name_1指向字符的另一個陣列或

  • 你可以把它作爲一個數組..

+0

非常感謝先生。我對此感到困惑很多,現在我很好。所以我永遠無法這樣做。只有通過分配空間,我才能使用代碼。 –

+0

通過給數組分配空間?我認爲你面臨的問題是理解指針。我建議你閱讀[this](http://pdos.csail.mit.edu/6.828/2012/readings/pointers.pdf) – Shash

+0

謝謝先生。我正在使用指針面臨麻煩。我通常使用數組而不是指針。 –