簡體   English   中英

C Char指針

[英]C Char pointers

讓我們說我們有一系列指針:

char *ptr[30];

現在這個工作正常,似乎沒有做任何意想不到的事情! 我可以輕松輸入名字。

scanf("%s", ptr[1]);
scanf("%s", ptr[2]);
scanf("%s", ptr[3]);

printf("%s\n", ptr[1]);
printf("%s\n", ptr[2]);
printf("%s\n", ptr[3]);

我的問題是,如果一個指針可以用這種方式來存儲名稱的結尾數,那么為什么要使用malloc呢? 在這種情況下,ptr [1]不指向輸入中的字符,而是指向新輸入本身。 例如,如果ptr有mukul,ptr [1]應該指向'u',如果在指定這樣的指針時沒有分配空間,那么限制是多少?

指針不能以這種方式使用。 它有時可能通過純粹的機會“起作用”,但使用指針而不為其分配內存將導致未定義的行為 - 這意味着您的程序可能表現不正常並給您意想不到的結果。

請記住,僅僅因為您的程序編譯和運行並不意味着它是正確的。 在C語言中,存在一類稱為“未定義行為”的錯誤,其中許多編譯器很樂意讓您無需抱怨。 這些包括使用未初始化的變量覆蓋緩沖區,或者取消引用不指向合法分配的內存塊的指針。 顯示未定義行為的程序有時甚至可能正常工作 - 但它們通常非常不穩定並且容易崩潰。

如果你使用你的例子中的內容,你只需要在你的ptr數組之后寫下其他位置。 大多數編譯器實際上應該至少給出一個警告。 您的程序會在大多數系統上崩潰,您只是非常幸運。

定義指針時:

char *ptr = 0; // NULL pointer: dereferencing it will crash
puts(ptr);    // crash

您只需創建一個指向內存中某個位置的鏈接:

ptr = "string"; // dereferencing it will show the string
puts(ptr);     // displaying "string"

因此,擁有一個指針數組只會創建一個對其他變量的引用列表。

要引用在內存中的地方,你必須變量分配給您的指針,或者每個指針分配內存。

你已經為30個指針分配了空間,但你沒有初始化它們指向任何有意義的地方。 除非您在函數外部聲明了數組,否則數組中的每個元素都將包含一些隨機位字符串,該字符串可能與可寫內存位置相對應,也可能不相對應。 如果我們繪制一張圖片,它看起來就像這樣(所有地址都是憑空而來的;不要假設這對應於任何真實的架構):

Item       Address       0x00  0x01  0x02  0x03
----       -------       ----  ----  ----  ----
ptr        0xbbc81230    0x??  0x??  0x??  0x??
           0xbbc81234    0x??  0x??  0x??  0x??
           0xbbc81238    0x??  0x??  0x??  0x??
           ...
           0xbbc812a8    0x??  0x??  0x??  0x??

其中0x?? 表示隨機字節值。 對於你所描述的行為,每個隨機值恰好指向可寫內存,並且寫入存儲在那里的任何內容恰好沒有任何直接的不良影響。

壞juju: 看起來你的代碼工作正常,但實際上它的表現非常糟糕,並且可能導致程序中其他地方出現一些令人討厭的運行時問題,這是一個很難調試的問題。

在嘗試寫入之前,您需要顯式設置ptr數組的每個元素以指向有效的內存位置。

假設我們添加以下代碼:

ptr[0] = malloc(strlen("foo") + 1);
strcpy(ptr[0], "foo");
ptr[1] = malloc(strlen("bar") + 1);
strcpy(ptr[1], "bar");

我們動態分配了一些額外的內存來保存幾個字符串,並將指針存儲到ptr[0]ptr[1]新緩沖區。

我們的圖片現在看起來像這樣:

Item       Address       0x00  0x01  0x02  0x03
----       -------       ----  ----  ----  ----
           0x80ff0000     'f'   'o'   'o'  0x00
           ...
           0x80ffcdc0     'b'   'a'   'r'  0x00
           ...
ptr        0xbbc81230    0x80  0xff  0x00  0x00
           0xbbc81234    0x80  0xff  0xcd  0xc0
           0xbbc81238    0x??  0x??  0x??  0x??
           ...
           0xbbc812a8    0x??  0x??  0x??  0x??

ptr[0]現在包含一個緩沖區的地址,其大小可以容納4個char值,我們將字符串“foo”復制到該緩沖區。 類似地, ptr[1]包含另一個4字節緩沖區的地址,該緩沖區現在包含字符串“bar”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM