2013-03-22 101 views
1

我正在運行一個函數,並在第10行出現錯誤。在gdb上調試時,我看到ptr指向0x0。我假設這是指關於無效地址位置的內容。爲什麼是這樣的,又如何再次修復代碼。謝謝指針指向無效的位置錯誤C

1 static char *kstrdup(const char *buf) 
2 { 
3  char *ptr, *ret; 
4 
5  ret = ptr = kmalloc(strlen(buf) + 1); 
6  if ((ptr = NULL)) 
7   panic("kmalloc returned NULL"); 
8 
9  for (; *buf != '\0'; ++ptr, ++buf) 
10  *ptr = *buf; 
11 
12 *ptr = '\0'; 
13 
14 return ret; 
15 } 

回答

4

這就是問題所在:

if ((ptr = NULL)) 

,因爲它作爲一個分配而不是比較。如果將NULL指定爲ptr,並且賦值結果爲零,表示條件爲false,並且未輸入if(),並且不調用panic()(該函數可能會退出程序)。剩下的代碼然後解引用NULL指針,這是未定義的行爲。

更改爲:

if (ptr == NULL) /* or if (!ptr) 

有些人希望把一個const值時,可在相等性檢查的左側,因此編譯器可以檢測這個錯誤幫助。例如,如果你這樣寫:

if (NULL = ptr) 

編譯器會發出一個錯誤(如左操作數必須是左值)和編譯就失敗了。

+0

或更好的是,改變它到'if(ptr == NULL)'。有些愚蠢的編譯器在看到一個雙括號時會壓制警告。如果編譯器不是愚蠢的,它會給出這個代碼的警告。 – Lundin 2013-03-22 12:40:02

+0

@Lundin,謝謝,那就是我的意思是(複製並粘貼!) – hmjd 2013-03-22 12:41:10

+0

在條件中首先使用常量編寫代碼...而不是if(ptr == NULL)if(NULL == pointer)這是因爲如果/當你意外地忽略了第二個'='並且將你的條件轉化爲一個賦值時,編譯器會忽略爲一個常量賦值的嘗試,這是避免你的微妙運行時錯誤的簡單方法碼。 – 2013-03-22 12:43:04

0

關於賦值和比較之間的區別有一個很好的教程。它非常好,你會潛意識地知道什麼時候使用分配以及何時使用比較。它是由KN King在他的偉大着作http://www.amazon.com/c/knking「> C編程:一種現代的方法。讀取一次。BTW ==屬於< <= > >= !=