2015-04-07 67 views
1

想象我下面的結構使用sizeof的malloc結構指針的正確方法是什麼?

struct Memory { 
    int type; 
    int prot; 
}; 

typedef struct Memory *Memory; 

我將如何使用malloc它初始化()?

Memory mem = malloc(sizeof(Memory)); 

Memory mem = malloc(sizeof(struct Memory)); 

什麼是分配正確的方法是什麼?

+5

您的'typedef'在很多層面上都是錯誤的......這是一個等待發生的事故,真的。無論哪種方式,寫'struct memory {};'然後像這樣分配'struct memory * mem = malloc(sizeof * mem);' –

+0

你認爲你需要分配一個對象多少內存?也許你想分配的對象類型的大小? – juanchopanza

+0

@EliasVanOotegem謝謝。那麼它應該是什麼大小?它是8個字節還是4個字節? – moeseth

回答

2

兩個

typedef struct Memory * Memory; 

是錯誤的。做正確的方法是:

typedef struct memory 
{ 
    int type; 
    int prot; 
} *MEMPTR; 

struct memory 
{ 
    int type; 
    int prot; 
}; 

typedef struct memory *MEMPTR; 

結構的名稱應該比一個指向它的名字不同。

8

你的struct聲明有點混亂了,typedef在很多層次上都是錯誤的。下面是我建議:

//typedef + decl in one 
typedef struct _memory { 
    int type; 
    int prot; 
} Memory; 

然後分配如下所示:

Memory *mem = malloc(sizeof *mem); 

閱讀malloc調用就像這樣:「分配的內存來存儲任何類型mem指向所需的量」。如果更改Memory *memMemory **mem,它會分配4首或8個字節(取決於平臺),因爲目前的情況是,它可能會分配8個字節,取決於int的大小,以及如何編譯器墊結構check wiki for more details and examples

使用sizeof *<the-pointer>被普遍認爲是分配內存的更好的辦法,但你想,你可以這樣寫:

Memory *mem = malloc(sizeof(Memory)); 
Memory *mem = malloc(sizeof(struct _memory)); 

他們都做同樣的事情。請注意,如果你是一個結構體,那可能是因爲你想抽象某個東西的內部運作,並且想編寫一個類的API。在這種情況下,你應該鼓勵使用struct _memory儘可能,有利於Memory*<the-pointer>反正

如果你想typedef指針,那麼你可以這樣寫:

typedef struct _memory { 
    int type; 
    int prot; 
} *Memory_p; 

在其中情況下,這個:

Memory_p mem = malloc(sizeof *mem); 

威力似乎直覺,但是否正確,如:

Memory_p mem = malloc(sizeof(struct _memory)); 

但這:

Memory_p mem = malloc(sizeof(Memory_p)); 

是錯誤的(它不會分配的結構所需的內存,但內存來存儲指向它)。

這是個人喜好,也許是一個問題,但我個人覺得typedef的朦朧某些事情。在許多情況下,這是更好的(即FILE*),但是一旦API開始隱藏你正在使用指針的事實,我就開始擔心一點。它往往使代碼更難以閱讀,調試和文檔...

試想一下這樣的:

int *pointer, stack; 

*運營商修改一個給定類型的變量,指針的typedef做到這些。這只是我的看法,我確信有許多程序員比我更擅長使用指針typedef。
大多數時候,雖然,指針typedef伴隨着定製分配功能或宏觀的,所以你不必奇怪的前瞻性陳述寫這樣Memory_p mem = malloc(sizeof *mem);,而是你可以寫ALLOC_MEM_P(mem, 1);它可以定義爲:

#define ALLOC_MEM_P(var_name, count) Memory_p var_name = malloc(count * sizeof *var_name) 

什麼

+1

即使在抽象的情況下 - 通過使用不完整/不透明類型來隱藏結構成員,我仍然不會隱藏typedef中的指針。因爲如果你這樣做,用戶會將該類型的變量視爲一塊數據而不是指針。而在不完整/不透明的情況下,您將分配給該代碼模塊的「成員函數」,而不是給用戶。 [這裏是一個例子](http://stackoverflow.com/questions/13032015/how-to-implement-a-class-in-c/13032531#13032531)。 – Lundin

+0

@倫丁:我完全同意。我不認爲指針typedefs是一個好主意,我想我明確表示(如果沒有,我會編輯我的答案)。我也同意你的看法,如果你在某個頭文件中輸入了一個不完整的類型,你就需要提供一個完整的API,包括分配函數,就像[我正在使用的庫]一樣(https ://github.com/edenhill/librdkafka)**不**使用指針typedefs但使用不完整的類型 –

2

這種結構

struct { 
    int type; 
    int prot; 
} Memory; 

定義了名稱Memory的對象具有無名結構的類型。

因此下一施工

typedef struct Memory *Memory; 

定義1)的新型struct Memory具有什麼共同與上述的定義和名稱內存。和2)指向struct Memory的另一新類型名稱Memory

如果兩個結構是存在於相同的編譯單元然後因爲名稱Memory(指針的名稱)在typedef聲明試圖重新聲明與無名結構的類型的對象中的編譯器將發出一個錯誤同名Memory

我想你指的是以下

typedef struct Memory { 
    int type; 
    int prot; 
} Memory; 

在這種情況下,你可以使用使用malloc的兩個記錄,如

Memory *mem = malloc(sizeof(Memory)); 

struct Memory *mem = malloc(sizeof(struct Memory)); 

Memory *mem = malloc(sizeof(struct Memory)); 

struct Memory *mem = malloc(sizeof(Memory)); 

因爲現在的兩個標識符存儲器是在兩個不同的名稱空間,第一個是用於與標籤struct和第二而不標籤結構體使用。

+0

我修復了我認爲代碼中存在錯誤的內容。請確認我沒有破壞任何東西。 – anatolyg

+0

@anatolyg謝謝。似乎有錯別字。 –

相關問題