[英]Dynamic memory allocation for structs in c
我正在嘗試通過向其分配內存以及使用malloc的指針成員來初始化結構:
typedef struct {
char *name;
prob_t *prob;
} name_t;
我了解,一旦初始化結構,就需要分別為指針分配內存:
name_t
*init_name_dict() {
name_t *name_dict;
name_dict = (name_t*)malloc(MAX_LINES*sizeof(*name_dict));
name_dict->name = (char*)malloc(MAX_LEN*sizeof(*name_dict->name));
name_dict->prob = (prob_t*)malloc(MAX_PROB*sizeof(*name_dict->prob));
return name_dict;
}
但是,當我這樣做時,它將內存分配給該結構,而不分配給它的任何成員指針(它們只是指向垃圾)。
我究竟做錯了什么? 謝謝
正如解釋在這里 , malloc
不“干凈”的記憶,那則可以滿是垃圾(例如因為相同的內存是由另一個調用返回malloc()
使用,然后free()
三種經典解決方案是:
struct
之前,先手動設置struct
所有成員(如果使用malloc
分配struct
)(或通常將所有獲得的內存設置為所需的值) memset
將所有內存歸零后再使用 calloc
代替malloc
(請注意,其簽名略有不同)。 calloc
與malloc
+ memset
相似。 舉個例子: name_t *init_name_dict() {
name_t *name_dict;
name_dict = calloc(MAX_LINES, sizeof(*name_dict));
name_dict->name = calloc(MAX_LEN, sizeof(*name_dict->name));
name_dict->prob = calloc(MAX_PROB, sizeof(*name_dict->prob));
return name_dict;
}
附帶說明一下,在C中,您不需要/也不應該calloc
malloc
/ calloc
返回的指針( 但是實際上,如果您使用的是C ++編譯器,則必須強制轉換... )。
如果要清除內存(而不是其中包含垃圾的內存),則需要calloc
而不是malloc
,但這很簡單。
您更大的問題是:
1) no error checking
2) possibly needless malloc calls
3) you're allocating MAX_LINES of theses name_t structure but initializing
only one of them
如果.name
和.prob
字段不會被重新分配,則應將name_t
定義更改為
typedef struct { char name[MAX_LEN]; prob_t prob[MAX_PROB]; } name_t;
並一次性分配所有MAX_LINES name_t: calloc(MAX_LINES, sizeof(name_t))
。
如果您需要原始的name_t
結構,則可以使用一個初始化程序:
int init_name_dict (name_t *this)
{
if(0==(this->name=calloc(MAX_LEN, sizeof *this->name))) return -1;
if(0==(this->prob=calloc(MAX_PROB, sizeof *this->prob))){ free(this->name); return -1; }
return 0;
}
破壞者
void destroy_name_dict(name_t *this) { free(this->name); free(this->prob); }
然后是整個數組的初始化分配器:
name_t* new_name_dicts(void)
{
name_t *r = malloc(MAX_LINES*sizeof *r);
if(!r) return r;
int i;
for(i=0; i<MAX_LINES; i++)
if(0>init_name_dict(&r[i])) goto fail;
return r;
fail:
for(--i; i>=0; --i)
destructor_name_dict(&r[i]);
return NULL;
}
(基本上,相當於為單元格類型選擇構造函數的C ++向量構造函數。)
結構
typedef struct {
char *name;
prob_t *prob;
} name_t;
有兩個指針作為成員。 因此,在32位OS上, sizeof(name_t)
為8個字節。 動態創建name_t
結構實例
name_t *name_dict = (name_t*)malloc(sizeof(name_dict));
僅分配8個字節來存儲兩個指針。 正如xanatos所說,分配的內存是垃圾,指針將指向隨機位置。 您可以在分配name_dict
時使用calloc()
或將其手動無效化name_dict->name = NULL;name_dict->prob = NULL;
。 您也可以不必擔心指針的內容,並且在下一行代碼中將內存分配給成員
name_dict->name = (char*)malloc(MAX_LEN*sizeof(char));
name_dict->prob = (prob_t*)malloc(sizeof(prob_t));
您還可以檢查內存分配是否良好,並且兩個指針都不指向NULL。
總結一下,正確編寫的init_name_dict()方法
name_t * init_name_dict()
{
name_t *name_dict = (name_t*)malloc(sizeof(name_t));
if (name_dict != NULL)
{
name_dict->name = (char*)malloc(MAX_LEN*sizeof(char)));
name_dict->prob = (prob_t*)malloc(sizeof(prob_t));
}
return name_dict;
}
您的代碼中的錯誤是
此處有MAX_LINES個(假設您只想在此處創建一個結構)
name_dict = (name_t*)malloc(MAX_LINES*sizeof(*name_dict));
此處為MAX_PROB(假設您僅想在此處創建一個結構)
name_dict->prob = (prob_t*)malloc(MAX_PROB*sizeof(*name_dict->prob));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.