我是 C 新手,對特定指標宣告有疑問:
這是我寫的一個程式:
#include <stdlib.h>
struct n {
int x;
int y;
};
int main()
{
struct n **p = malloc(sizeof(struct n));
return 0;
}
這里的宣告不正確,但為什么不正確?
這是我的思考程序:
- 的手冊頁
malloc指定它回傳一個指標:
The malloc() and calloc() functions return a pointer to the
allocated memory, which is suitably aligned for any built-in
type.
的型別
p也struct n**就是指向另一個指標的指標。但是這個宣告不應該在理論上起作用,因為:
malloc回傳型別struct n*(指標)- 并
p指向malloc回傳的指標 - 所以它本質上是一個指向另一個指標的指標
- 所以
p滿足的型別
對不起,如果這是一個愚蠢的問題,但我真的很困惑為什么這不起作用。感謝您提前提供任何幫助。
uj5u.com熱心網友回復:
mallocis not的回傳型別struct n *,不管它是如何被呼叫的。的回傳型別malloc是void *。
struct n **使用type 的值初始化物件void *會將其隱式轉換為struct n **. 這種隱式轉換是允許的,因為初始化規則遵循 C 2018 6.5.16.1 1 中的賦值規則,其中允許的賦值之一是:
…左運算元具有原子、合格或非限定指標型別,并且(考慮左運算元在左值轉換后將具有的型別)一個運算元是指向物件型別的指標,另一個是指向合格或非限定版本的指標of
void,并且左邊指向的型別具有右邊指向的型別的所有限定符;…
- 并
p指向malloc回傳的指標
不,該值p被初始化為malloc回傳的值。然后p指向malloc分配的記憶體。
這段代碼為 a struct n(using malloc(sizeof(struct n))) 分配足夠的空間但將該空間的地址分配給struct n **that is 是錯誤的p。指向一個struct n,使用struct n *p = malloc(sizeof (struct n));,或者,最好是,struct n *p = malloc(sizeof *p);。
要指向指向 a 的指標struct n,首先創建一些指向 a 的指標struct n,與上面一樣struct n *p = malloc(sizeof *p);。然后指向該指標的指標將是struct n **pp = &p;.
如果你想為那些指向指標的指標分配空間,你可以用 with 來做,然后你可以用withstruct n **pp = malloc(sizeof *pp);填充指標。但是,您不應在沒有充分理由的情況下添加此額外的分配層。struct n*pp = malloc(sizeof **pp);
請注意,MyPointer = malloc(sizeof *MyPointer);通常首選表單,MyPointer = malloc(sizeof (SomeType));因為前者會自動使用MyPointer指向的型別。后者容易出錯,例如有人誤解了 of 的型別MyPointer而沒有SomeType正確設定,或者有人后來更改了 of 的宣告,但沒有在呼叫中MyPointer對 to 進行相應的更改。SomeTypemalloc
uj5u.com熱心網友回復:
這真的行不通。在此示例中,malloc 回傳一個 void *,它指向堆中新分配的位置,該位置大到足以容納結構 n。
請注意,malloc() 回傳型別 void *,它基本上是指向任何潛在型別的指標,malloc() 不回傳型別 struct n *(指向您宣告的結構型別的指標)。void * 具有能夠被強制轉換為任何其他型別的指標并再次回傳的特殊屬性。
總之,這意味著您的代碼實際上不起作用,因為您的 struct n** 的第一個取消參考將是一個 struct n,而不是一個 struct n*。如果您嘗試取消參考兩次,您很可能會得到無效的記憶體參考并崩潰。
您的代碼可以編譯和運行而不會崩潰的原因是:
- 編譯器自動將 void * 轉換為 struct n **
- 您永遠不會嘗試實際取消參考您的指標,這意味著您永遠不會嘗試無效的記憶體參考。
uj5u.com熱心網友回復:
簡化問題和理解可能會來:
int main()
{
struct n data;
struct n *pData = &data; // skipped in your version
struct n **ppData = &pData;
// struct n **ppData = &data; // Will not compile
// struct n **ppData = (struct n **)&data; // Casting but wrong!
return 0;
}
因為malloc()回傳一個 void ptr,所以您可以自由地將指標存盤到任何指標資料型別中。如果您將其放入錯誤的資料型別中,您會頭疼...
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/506510.html
