簡體   English   中英

語言 C 中的免費問題不起作用

[英]Problem with free in language C which doesn't work

我寫了這個程序,我想釋放一個結構myStruct但它沒有編譯它說:

free():在 tcache2 中檢測到雙重釋放

你能幫我嗎?

#include <stdio.h>
#include <stdlib.h>

typedef struct myStruct {
    char* chaine;
    struct myStruct* next;
} mystruct;

void supprimer(myStruct* D) {
    free(D->chaine);
    free(D);
}

int main()
{
    myStruct* D = malloc(sizeof(myStruct));
    D->next = NULL;
    char* chaine = malloc(sizeof(char)*10);
    chaine = "ouii";
    D->chaine = chaine;
    supprimer(D);
    printf("Hello World");

    return 0;
}

我試圖通過創建新結構並刪除它來運行 main,但它不起作用。

chaine = "ouii"; 是錯的。 這不會將“ouii”復制到 chaine 指向的chaine中,它會將指針chaine設置為指向為字符串文字"ouii"創建的數組。 該地址不應傳遞給free

更改chaine = "ouii"; strcpy(chaine, "ouii"); .

char* chaine = malloc(sizeof(char)*10);
    chaine = "ouii";

第二條語句更改了chaine最初指向的內容(即指向 malloc 返回的堆malloc區域的指針),使其現在指向字符串文字ouii 現在您已經失去了對 malloc 返回的原始malloc的訪問權限(內存泄漏),並且正在嘗試free memory 分配函數之一未返回的 memory。 因此警告。

可能的修復:

  • 使用標准strcpy復制字符串。

     strcpy (chaine, "ouii");

    並將#include <string.h>添加到標頭列表中。


旁白: malloc在失敗時返回NULL 在訪問它之前,您應該檢查指針是否有效。 它還在 POSIX 兼容系統上將errnoENOMEM 這是我更喜歡在main ()中處理它的一種方式:

#include <errno.h>

errno = 0;
char *chaine = malloc (10); /* sizeof (char) is defined to be 1 */

if (!chaine) {
    errno = ENOMEM;
    perror ("malloc");
    return EXIT_FAILURE;
}

另見: How do I modify a char** in another function

這段代碼片段

char* chaine = malloc(sizeof(char)*10);
chaine = "ouii";

導致 memory 泄漏。

一開始動態分配了一個memory,地址賦值給指針chaine

char* chaine = malloc(sizeof(char)*10);

然后指針被重新分配為字符串文字"ouii"的第一個字符的地址

chaine = "ouii";

所以動態分配的地址memory丟失了。

而不是這個任務

chaine = "ouii";

您需要使用 header <string.h>中聲明的標准字符串 function strcpy將字符串文字的字符復制到動態分配的 memory 中。 例如

#include <string.h>

//...

char* chaine = malloc(sizeof(char)*10);
strcpy( chaine, "ouii" );

注意這個function

void supprimer(myStruct* D) {
    free(D->chaine);
    free(D);
}

使在 main 中聲明的指針D

myStruct* D = malloc(sizeof(myStruct));

無效的。

最好通過引用將指針傳遞給 function。

在 C 中,通過引用傳遞意味着通過指向它的指針間接傳遞 object(包括指針)。 因此取消引用指針,您將可以直接訪問指針指向的 object 並可以更改它。

另外,您似乎想要定義一個單鏈表,那么 function 可以看起來像以下方式

void supprimer( myStruct **D ) 
{
    while ( *D != NULL )
    {
        myStruct *current = *D;
        *D = ( *D )->next;
        free( current->chaine );
        free( current );
    }
}

function 被稱為

supprimer( &D );

在這種情況下,調用 function 后,main 中定義的指針D將等於NULL

注意檢查memory是否分配成功,避免未定義行為。

這是一個演示程序,展示了如何實施您的列表。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct myStruct
{
    char *chaine;
    struct myStruct *next;
} mystruct;

int push ( myStruct **D, const char *chaine )
{
    myStruct *current = malloc( sizeof( *current ) );
    int success = current != NULL;

    if (success)
    {
        current->chaine = malloc( strlen( chaine ) + 1 );
        success = current->chaine != NULL;

        if (success)
        {
            strcpy( current->chaine, chaine );
            current->next = *D;
            *D = current;
        }
        else
        {
            free( current );
        }
    }

    return success;
}

void supprimer( myStruct **D )
{
    while (*D != NULL)
    {
        myStruct *current = *D;
        *D = ( *D )->next;
        free( current->chaine );
        free( current );
    }
}

void output( const myStruct *D )
{
    for ( const myStruct *current = D; current != NULL; current = current->next )
    {
        printf( "\"%s\" -> ", current->chaine );
    }

    puts( "null" );
}

int main( void )
{
    myStruct *D = NULL;

    push( &D, "World" );
    push( &D, "Hello" );

    output( D );

    supprimer( &D );
}

程序 output 是

"Hello" -> "Word" -> null

暫無
暫無

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

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