Fw: [問題] 指標的指標問題
※ [本文轉錄自 C_and_CPP 看板 #1EMIxS0J ]
作者: tropical72 (藍影) 看板: C_and_CPP
標題: Re: [問題] 指標的指標問題
時間: Sun Aug 28 01:52:24 2011
別再寄私信給我了,我已建議一些書,
找不到相關說明,或沒畫圖的,該再找一些書,
再不然,請善用你手邊 VS 逐步偵錯功能,
或發表出來讓其他版友有機會為你服務,
BBS 畫記憶體配置圖真不是件容易的事..
※ 引述《kswiss11 (kswiss)》之銘言:
: {
: *p1=(char*)malloc(16);
: strcpy(*p1, "Hello");
: }
: void main()
: {
: char*p=NULL;
Var. p
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│ │ │ │ │ │ │ │ │ │ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │ 0 │ │ │ │ │ │ │ │ │ │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
: printf("%p\n", &p);
0x12 (address of pointer)
: test(&p);
呼叫時,記憶體再配一個新的 p1,裡面存 p 之位址值,開始進入副函式
void test(char** p1)
Var. p p1
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│... │ │?? │ │ │ │ │ │ │ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │ 0 │... │ │0x12│ │ │ │ │ │ │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
{
*p1=(char*)malloc(16); /* equ. below lines. */
char * t = (char*)malloc(16); /* (1) */
* p1 = t; /* (2) */
(1) char* t = (char*)malloc(16);
t 指向新配置 16 個空間之開頭
Var. p p1 t t+1 t+2 ... t+15
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│... │ │?? │... │0x80│0x81│0x82│... │0x8f│ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │ 0 │... │ │0x12│... │??? │?? │ ?? │... │ ?? │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
(2) *p1 = t;
將 t 之位址,設給 (p1 指向記憶體位址) 之內容
Var. p p1 t t+1 t+2 ... t+15
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│... │ │?? │... │0x80│0x81│0x82│... │0x8f│ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │0x80│... │ │0x12│... │????│?? │ ?? │... │ ?? │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
strcpy(*p1, "Hello");
將 (p1 指向位置) 指向位置,設成 'H' 'E' 'L' 'L' 'O' '\0'
Var. p p1 t t+1 t+2 ... t+16
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│... │ │?? │... │0x80│0x81│0x82│... │0x8f│ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │0x80│... │ │0x12│... │'H' │'E' │ 'L'│... │ ?? │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
0x80 'H' , 0x81 'E', 0x82 'L', 0x83 'L', 0x84 'O', 0x85 '\0'
0x86~0x8f ????
}
回到主程式後
Var. p
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│... │ │ │... │0x80│0x81│0x82│... │0x8f│ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │0x80│... │ │ │... │'H' │'E' │ 'L'│... │ ?? │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
: printf("%s\n", p);
輸出 p 所指向位置之字串
從 0x80 開始輸出 'H', 一直輸出到 '\0',便輸出 "HELLO"
: }
最後加上 free(p);
p 內容雖仍不變,但其指向記憶體已不可使用
Var. p
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Addr │0x12│... │ │ │... │0x80│0x81│0x82│... │0x8f│ │
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
Value │0x80│... │ │ │... │??? │??? │ ???│... │ ?? │ │
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴
字串 / 陣列 / 指標 本身便不好理解,
加上 sub_function 實際傳遞機制使得問題更加混亂,
此處確實不好第一次學習就理解,你的書沒有,才跟你說多找幾本書。
----
補原 po 於推文中的問題,
*p=(char*)malloc(16);不就等於p=(char**)malloc(16);嗎??
如果改成p=(char**)malloc(16);
然後strcpy(*p, "Hello");
執行後會出現異常,為什麼???
那兩行並不相等。
char **p;
p = (char**)malloc(16);
這段寫法很危險,想想 malloc 較為一般性的寫法為何
資料型態 *p;
p = (資料態型 *)malloc(sizeof(資料型態) * 配置個數)
malloc 裡面實際要放的是,「總共記憶體需求量」。
----
以 char *p1 而言,
char *p1;
p1 = (char*)malloc(sizeof(char) * 16);
這裡是配置一個「一維字元陣列,陣列大小有 16 個元素」
也因為每個字元所佔記憶體大小為 1 ,
所以 sizeof(char) 都不寫。
----
再看 char* *p1,
char* *p1;
p1 = (char* *)malloc(sizeof(char*) * 16);
這和推文問得一樣,只是把 * 分開一點,所以看起來怪怪的。再看一次公式
資料型態 *p;
p = (資料態型 *)malloc(sizeof(資料型態) * 配置個數)
現在資料型態是 char*, pointer to char,
配置出來的是 「一維指標陣列」,p 本身是陣列,
陣列元素裡面放的是一堆「位址值」,因為資料型態是 pointer to char,
那 sizeof(char *) 多大?
這是另一個討論很久的問題,但你現在可不用知道,只需要知道,
1. sizeof(...) 不要省
2. char** p = (char**)malloc(...) 出來的是指標陣列
3. char* p = (char*)malloc(...) 出來的是字元陣列
4. char*** p = (char***)malloc(...) 出來的還是指標陣列
其他的,不要再讚牛角下去了。
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
推
08/28 01:55, , 1F
08/28 01:55, 1F
推
08/28 01:56, , 2F
08/28 01:56, 2F
推
08/28 01:58, , 3F
08/28 01:58, 3F
→
08/28 02:03, , 4F
08/28 02:03, 4F
推
08/28 02:05, , 5F
08/28 02:05, 5F
→
08/28 02:06, , 6F
08/28 02:06, 6F
→
08/28 02:07, , 7F
08/28 02:07, 7F
→
08/28 02:08, , 8F
08/28 02:08, 8F
→
08/28 02:05, , 9F
08/28 02:05, 9F
推
08/28 02:06, , 10F
08/28 02:06, 10F
推
08/28 02:10, , 11F
08/28 02:10, 11F
→
08/28 02:11, , 12F
08/28 02:11, 12F
→
08/28 02:11, , 13F
08/28 02:11, 13F
→
08/28 02:12, , 14F
08/28 02:12, 14F
→
08/28 02:12, , 15F
08/28 02:12, 15F
→
08/28 02:14, , 16F
08/28 02:14, 16F
→
08/28 02:15, , 17F
08/28 02:15, 17F
→
08/28 02:16, , 18F
08/28 02:16, 18F
推
08/28 02:18, , 19F
08/28 02:18, 19F
→
08/28 02:19, , 20F
08/28 02:19, 20F
推
08/28 02:20, , 21F
08/28 02:20, 21F
→
08/28 02:22, , 22F
08/28 02:22, 22F
→
08/28 02:23, , 23F
08/28 02:23, 23F
→
08/28 02:25, , 24F
08/28 02:25, 24F
→
08/28 02:26, , 25F
08/28 02:26, 25F
推
08/28 02:31, , 26F
08/28 02:31, 26F
→
08/28 02:32, , 27F
08/28 02:32, 27F
→
08/28 02:32, , 28F
08/28 02:32, 28F
→
08/28 02:33, , 29F
08/28 02:33, 29F
→
08/28 02:34, , 30F
08/28 02:34, 30F
推
08/28 02:34, , 31F
08/28 02:34, 31F
→
08/28 02:41, , 32F
08/28 02:41, 32F
→
08/28 02:45, , 33F
08/28 02:45, 33F
→
08/28 02:45, , 34F
08/28 02:45, 34F
→
08/28 03:01, , 35F
08/28 03:01, 35F
→
08/28 07:56, , 36F
08/28 07:56, 36F
→
08/28 07:57, , 37F
08/28 07:57, 37F
→
08/28 07:58, , 38F
08/28 07:58, 38F
推
08/28 10:25, , 39F
08/28 10:25, 39F
推
08/28 11:05, , 40F
08/28 11:05, 40F
→
08/28 12:13, , 41F
08/28 12:13, 41F
推
08/28 14:13, , 42F
08/28 14:13, 42F
→
08/28 14:48, , 43F
08/28 14:48, 43F
推
08/28 16:20, , 44F
08/28 16:20, 44F
推
08/28 16:30, , 45F
08/28 16:30, 45F
→
08/28 17:50, , 46F
08/28 17:50, 46F
→
08/28 19:21, , 47F
08/28 19:21, 47F
→
08/28 19:22, , 48F
08/28 19:22, 48F
你只知道用動態配置,但卻不知道配置出來的是什麼東西。
上面有給你一個公式了,
資料型態 *p;
p = (資料態型 *)malloc(sizeof(資料型態) * 配置個數)
所以
*p1=(char*)malloc(6);
配出來的不是指標陣列,而是字元陣列。
另上面提到了, 全部要寫 *p1 = (char*)malloc(sizeof(char) * 6);
sizeof(char) 是「單一元素大小」,6 指的是「元素個數」,
之所以把 sizeof(char) 拿掉 (我認為對初學者不是好作法),
是因為 sizeof(char) 剛好等於 1,也就是單一元素大小。
※ 編輯: tropical72 來自: 180.177.78.41 (08/28 19:42)
→
08/28 19:43, , 49F
08/28 19:43, 49F
→
08/28 19:50, , 50F
08/28 19:50, 50F
推
08/28 23:18, , 51F
08/28 23:18, 51F
推
08/29 00:23, , 52F
08/29 00:23, 52F
推
08/29 03:16, , 53F
08/29 03:16, 53F
推
08/29 03:55, , 54F
08/29 03:55, 54F
推
08/29 04:32, , 55F
08/29 04:32, 55F
推
08/29 12:21, , 56F
08/29 12:21, 56F
推
08/29 12:23, , 57F
08/29 12:23, 57F
→
08/29 12:47, , 58F
08/29 12:47, 58F
推
08/29 13:13, , 59F
08/29 13:13, 59F
→
08/29 13:31, , 60F
08/29 13:31, 60F
→
08/29 14:30, , 61F
08/29 14:30, 61F
推
08/29 19:32, , 62F
08/29 19:32, 62F
推
08/30 16:37, , 63F
08/30 16:37, 63F
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: azter (220.132.206.140), 11/28/2015 07:37:33