2012-04-29 88 views
1

我有下面的代碼行:的malloc的指針參數失敗

struct c_obj_thing *object = NULL; 
c_obj_initalizer(object); 
// at this point, (object == NULL) is 'true' 
printf("Value: %d\n", object->value); // this segfaults 

這裏是c_obj_initalizer的定義是:爲什麼在c_obj_initalizer方法中的malloc不能保持連接到

int c_obj_initalizer(struct c_obj_thing *objParam) { 
    objParam = malloc(sizeof(struct c_obj_thing)); 
    objParam->pointerThing = NULL; 
    objParam->value = 0; 
    return 0; 
} 

指針在方法返回時作爲參數傳遞?這似乎是對初創者的呼籲沒有做任何事情。我意識到,將實際的c_obj_thing作爲指針傳遞並不意味着initalizer中所做的更改不會返回,但我認爲動態內存會在整個程序中保持不變。

回答

4

因爲當你調用它發送指針的副本的功能,當你在函數改變它,你不調用方法改變。你需要在初始化之前使用malloc。

例如:

struct c_obj_thing *object = malloc(sizeof(struct c_obj_thing)); 
c_obj_initalizer(object); 
printf("Value: %d\n", object->value); // this segfaults 


int c_obj_initalizer(struct c_obj_thing *objParam) { 
    objParam->pointerThing = NULL; 
    objParam->value = 0; 
    return 0; 
} 
+1

啊,我明白了! Malloc只分配本地指針副本以指向新的內存。謝謝! – Tanaki 2012-04-29 05:13:03

2

如果需要出於某種原因做了功能c_obj_initalizer配置,你必須通過指針指向一個功能:

int c_obj_initalizer(struct c_obj_thing ** objParam) { 
    *objParam = malloc(sizeof(struct c_obj_thing)); 
    *objParam->pointerThing = NULL; 
    *objParam->value = 0; 
    return 0; 
} 

,比如呼叫這樣的:

struct c_obj_thing *object = NULL; 
c_obj_initalizer(&object); 
+1

雖然這在語法上是正確的,但是我會避免這樣做,僅僅因爲能夠在函數中使用malloc而發送雙指針是一種糟糕的編程習慣。你有所有額外的解引用,你必須把它釋放下來,如果你正在初始化多個對象,這可能很難遵循。 – drew212 2012-04-29 05:17:29

+0

@drew我同意你關於「誰是對象的所有者」這一問題的觀點,但有時你需要這樣做(因爲繼承設計)並堅持某種約定來決定誰是所有者。 – 2012-04-29 05:25:49