[英]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 兼容系統上將errno
為ENOMEM
。 這是我更喜歡在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;
}
這段代碼片段
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.