簡體   English   中英

C釋放結構指針成員

[英]C freeing struct pointer members

我已經聲明了以下結構:

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); 

這段代碼運行得很好。 但是,我認為,當您擁有一個帶有指針成員的結構時,應該對每個成員進行free() (除指向該結構的指針外)。

所以在這里,我沒有mallocroot->data (因為我認為malloc荷蘭國際集團的結構是做),但它被初始化為輸入值,它的價值被成功打印。 當我嘗試free(root->data)我的程序崩潰了。

所以root->datamalloc編輯時,我malloc root 如果沒有,我怎么仍可以使用它? 為什么會這樣? 我在這里想念什么?

首先,了解需要(或不需要)調用free()

您不需要malloc() “ for” root->data ,而當您分配的內存等於該結構的大小時,該變量已被分配。 現在,接下來,您當然需要root->data指向一些有效的內存,以便您可以取消引用指針以進行讀取和寫入。 您可以通過以下兩種方式之一

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

如果您要存儲由malloc()返回的指針,是的,您必須free()內存(但是),在這種情況下, root->data持有一個不是malloc()返回的指針,因此它不需要free() -在任一。

只是為了增加並強調與free()相關的部分,您一定不要嘗試free()先前未通過調用malloc()和family分配的內存,否則,它將調用未定義的行為 引用標准C11第§7.22.3.3章( 重點是我的

 void free(void *ptr); 

free函數使ptr指向的空間被釋放,即可以用於進一步分配。 如果ptr是空指針,則不執行任何操作。 否則, 如果參數與內存管理函數先前返回的指針不匹配,或者如果通過調用freerealloc釋放了空間,則該行為是不確定的。

當我嘗試釋放(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);

請注意,在繼續之前,您應該檢查malloc的結果

所以當我分配root時,不會分配root-> data嗎? 如果沒有,我怎么仍可以使用它?

還要注意對於空間root->data ,當您為分配內存分配struct ,但它不是malloc編輯。 如上例所示,您需要一個額外的malloc尤其是對於root->data 之所以需要root->data malloc是為了能夠取消引用指針。

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);

我已經在您的代碼中添加了一些注釋。

我希望這可以解決問題。

// 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時,不會分配root->data嗎?

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

如果沒有,我怎么仍可以使用它?

就像你一樣。 您為對象分配了一個內存地址,該地址的壽命足以供您使用。 您可以使用動態內存管理(然后注意在完成后手動銷毀它:不要泄漏內存)或完成后使用“自動內存管理”來產生此類對象(然后注意不要銷毀時間過早:請勿訪問無效的內存)。 (僅列舉創建對象的兩種可能方法...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM