2014-11-16 120 views
-1
#include <stdio.h> 
#include <string.h> 
#include <windows.h> 
#include <conio.h> 

void main(){ 
    void generateId(char*, char*); 

    char name[20]; 
    char id[7]; 
    printf("Enter your name: "); 
    scanf("%s", name); 
    generateId(name, id); 

} 

void generateId(char *name, char *id){ 

    char *ptrName = name; 
    char *ptrId = id; 
    puts(ptrName);//crashes if i used puts(*ptrName); 
} 

有人可以向我解釋上面的註釋行嗎?爲什麼程序崩潰時會給出小於20的有效輸入,如果我嘗試解引用指針?但是當我沒有解引用指針時,它並沒有崩潰。如果我解除引用,它不應該給我輸入的價值嗎?但是如果我不解除引用,它如何給我帶來價值?C指針解引用

+1

如果你編寫'puts(ptrName)',它甚至不應該編譯... –

回答

1

函數puts需要內存中以空字符結尾的字符串的地址。

在您的代碼中,變量ptrName確實指向內存中以null結尾的字符串。

但是通過調用puts(*ptrName),而是傳遞該字符串的第一個字符。

當傳遞給函數puts時,該字符的值被擴展爲地址的大小(通常爲4或8字節),並且該函數假定它指向有效的以null結尾的字符串。

該函數然後嘗試讀取該內存地址處的內容,這很可能會導致非法內存訪問(雖然正式它被認爲是未定義的行爲-任何事情都可能發生)。

+0

「函數puts需要在內存中以null結尾的字符串的地址。」從哪裏可以閱讀有關特定C函數的詳細信息,例如您所寫的內容? – sutoL

+1

@sutoL:打開http://www.google.com,在搜索框中輸入'puts',點擊輸入,等到您重定向到一個新的帶有網頁鏈接列表的網頁,選擇第一個非網頁 - 商業鏈接並打開它。 –

1

ptrName是一個指向char的指針。 * ptrName是char。函數puts把指針作爲參數,而不是char。當你這樣使用它時,它會嘗試將Char的值解釋爲一個會導致內存違規的指針。