2017-03-07 147 views
1

我有我已經聲明瞭以下結構:ç釋放結構指針成員

typedef struct binTreeNode 
{ 
    void *data; 
    struct binTreeNode *left; 
    struct binTreeNode *right; 
} myBinaryTreeNode; 

在我main功能,我試圖用一個指針叫root該結構的一個實例。

myBinaryTreeNode *root = malloc(sizeof(myBinaryTreeNode)); 
printf("\nPlease insert root data: "); 
int input; 
scanf("%d", &input); 
root->data = (void*)&input; 
printInt(root->data); 
free(root); 

此代碼運行良好。但是,我認爲,當你有一個指向成員的結構時,你應該每個都有一個指針(除了指向結構的指針)。所以在這裏,我沒有mallocroot->data(因爲我認爲malloc結構是這樣做的),但它被初始化爲輸入值,並且它的值被打印成功。當我嘗試free(root->data)我的程序崩潰。

所以root->data是不是malloc編輯當我malloc root?如果不是,我還能如何使用它? 這是爲什麼發生?我在這裏錯過了什麼?

+0

'所以root->數據不是malloced,當我malloc根?如果沒有,我還能如何使用它?'只需調用另一個malloc即可。 – Matt

+0

在你釋放你有指針的東西之前,最好確保它是你分配的東西。你是否分配了一些東西,並在結構中設置指針來指向它? – StoryTeller

回答

1

當我嘗試釋放(root-> data)時,我的程序崩潰了。

您不能free你沒有動態分配的內存。如果你想free的元素,你應該首先將它們分配是這樣的:

typedef struct binTreeNode 
{ 
    int *data; 
    struct binTreeNode *left; 
    struct binTreeNode *right; 
} myBinaryTreeNode; 

root->data = malloc(sizeof(int)); 
if (root->data == NULL) 
{ 
    printf("Error allocating memory\n"); 
    return; 
} 
scanf("%d", root->data); 
free(root->data); 

請注意,您應該check the result of malloc繼續之前。

所以root->數據是不是malloced當我malloc根?如果不是,我還能如何使用它?

還要注意,當您爲struct分配內存root->data該空間分配,但它不是malloc版。您需要額外的malloc,尤其是root->data,如上例所示。你需要mallocroot->data的原因是能夠解引用指針。

3

首先,獲得你需要(或不必)撥打free()的地點和方式的概念。

你不需要malloc()「爲」root->data,當你分配的內存等於結構的尺寸可變的已分配。現在,接下來,您當然需要root->data指向一些有效的內存,以便您可以取消引用指針讀取並寫入它。你可以通過以下兩種方式

  • 店是有效的地址(如你的情況,提供一個已經存在的變量的地址)
  • 分配由另一malloc()(成功)返回一個指針。

在情況下,你存儲通過malloc()返回的指針,是必須free()內存,但在你的情況,root->data具有指向不malloc()返回,所以它不需要free() -in無論是。

我想補充和強調的部分相關free() -ing,你不能企圖free()尚未通過調用預先分配給malloc()和家人,否則內存,它調用undefined behavior。引述,標準C11,章§7.22.3.3,(重點煤礦

void free(void *ptr); 

free功能使空間指向ptr被釋放,也就是由 可用於進一步分配。如果ptr是空指針,則不會發生任何操作。否則,如果的 參數不匹配早些時候內存管理 功能,返回一個指針,或者如果空間已被釋放通過調用freerealloc的 行爲是不確定的。

1

data成員指向input局部變量,所以你不能釋放它。

必須釋放會員,如果你動態地分配它們,就像

typedef struct binTreeNode 
{ 
    int *data; 
    struct binTreeNode *left; 
    struct binTreeNode *right; 
} myBinaryTreeNode; 

root->data = malloc(sizeof(int)); 
scanf("%d", root->data); 
free(root->data); 
+0

@paddy Ty爲您編輯。 – LPs

+0

感謝您的回答!那麼'輸入'和相似的內存怎麼會最終被釋放?而且,比另一種更好嗎? –

+0

'input',作爲本地作用域變量,具有[自動存儲](https://en.wikipedia.org/wiki/Automatic_variable)。 – LPs

1

我增加了一些註釋你的代碼。

我希望這可以解決問題。

// I have added an enclosing block for the purpose of demonstration: 
{ 
    // Here you allocate memory for a tree node object with dynamic/allocated 
    // storage duration. 
    // That is: three pointers, that point to nowhere are created and will 
    // exist until the memory holding them is free'd. 
    myBinaryTreeNode *root = malloc(sizeof(myBinaryTreeNode)); 
    printf("\nPlease insert root data: "); 
    // Here you create an object with automatic storage duration. 
    // That is, the object is automatically destroyed when the function 
    // returns or the block is closed: { ... } 
    int input; 
    // here you attempt to assign a value to the variable 
    // (you should check the return value: the input may fail) 
    scanf("%d", &input); 
    // Here you assign the address of an object to a pointer. 
    // Note that you are only allowed to use the pointer as long as the 
    // object it points to "lives". 
    root->data = (void*)&input; 
    // Here you probably print the value, or the pointer address, or something else 
    printInt(root->data); 
    free(n); // <-- Where and how did you allocate this? 
    // Here you free the memory holding the tree node 
    free(root); 
} // <-- At this point the "input" variable is automatically destroyed. 

你真的應該閱讀了關於不同存儲的持續時間(分配的自動和動態/)動態內存分配的目的:


爲了解決具體問題:

當我嘗試free(root->data)我的程序崩潰。

那是因爲你只能free()你有什麼malloc()。對於不同類型的存儲時間,內存管理是不同的。

所以root->data是不是malloced當我malloc根?

分配指針的內存,但默認情況下它不會「擁有」或「指向」任何對象。

如果不是,我該如何使用它?

就像你那樣。你爲它分配一個對象的內存地址,它的存活時間足夠你使用它。你可以使用動態內存管理來生成這樣的對象(然後一定要在你完成後手動銷燬它:不要泄漏內存),或者像你所做的那樣使用「自動內存管理」(然後注意它不是過早銷燬:不要訪問無效內存)。 (僅舉兩種創建對象的可能方式......)