2016-07-20 65 views
0

我是C新手,請和我一起裸照。據我所知,下面的代碼,因爲它試圖寫入內存的一部分,其中q點(一些隨機地址),這部分內存是不允許通過給定的過程寫返回分段錯誤:爲什麼聲明指針指向未知內存,而定義不是?

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

int main(){ 
    char* p = "Hello"; 
    char* q; 

    strcpy(q, p); 
    printf("%s\n", q); 
} 

我也理解,它可以通過動態分配的內存適量指向q這個記憶很容易固定,所以p內容可以被安全地複製到q

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

int main(){ 
    char* p = "Hello"; 
    char* q = (char*)malloc(6*sizeof(char)); 

    strcpy(q, p); 
    printf("%s\n", q); 
} 

但是,爲什麼下面的例子是工作?

#include <stdio.h> 

int main(){ 
    char* p = "Hello"; 
    printf("%s\n", p); 
} 

是不是char* p = "Hello";還指着這是不允許的給出過程寫一些未知的記憶?

+0

@ user3121023哦,那是學者的錯誤感謝。我刪除了第二個問題不要混淆。 –

+0

投票給我的人請註明原因,這樣我就可以改善這個問題。謝謝 –

+0

由於[@Xaver](http://stackoverflow.com/a/38485137/2410359)回覆了刪除的部分帖子,帖子現在更加令人困惑。建議把它帶回禮服。 – chux

回答

2

代碼

char* p = "Hello"; 

創建六個字符的數組,並將它們設置爲"Hello"(第六字符將是空字符)。然後,它將此數組的內存地址寫入p。所以p指向一個初始化的內存段。

關於你的第二個例子:p包含char數組的內存地址"Hello"。如果你想q包含相同的內存地址,您必須使用命令

​​

在代碼

q = &p; 

的類型是不兼容的,因爲q的類型是char*,而&p具有類型char**

1

當您編寫char* p = "Hello";時,編譯器將在運行時爲只讀的部分內存中創建一個char數組,填充爲{'H', 'e', 'l', 'l', 'o', '\0'}。指針p填充了該數組的地址。所以地址是有效的,它可以是讀取從安全但不寫入,它可以作爲一個可讀的字符串傳遞給C的字符串函數,並且你永遠不需要擔心字符串文字,因爲它們代表靜態陣列。

+0

爲什麼要投票?請告訴我我哪裏出了問題。 –

+0

字符串文字的類型不是常量。 – 2501

+0

編輯,謝謝。 –

1

當您編寫char *p = "Hello";時,編譯器會在內部創建一個const char[6]來保存字符串litteral,然後將其地址複製到p。不幸的是,字符串的類型不是const,所以你沒有得到任何警告,告訴你你正在放棄const屬性,但是字符串不能被修改。

所以p指向一個明確的內存區,你可以從它與printf("%s\n", p);

問題安全地讀取例如是該字符串litteral不得修改,並試圖使用指針寫像p[1] = 'a';調用未定義的行爲。在常見的實現中,編譯器實際上使用只讀段來存儲字符串文件,並且如果您嘗試覆蓋它,則會出現內存違例或段違例錯誤。

但它不是未知內存只是只讀之一。

+0

什麼是字符串litteral? –

相關問題