为什么在 C 中出现 double free 或 corruption 错误?我释放了我的 mallocs
Why double free or corruption error in C? I freed my mallocs
我收到此错误:
Error in `./sorter': double free or corruption (!prev): 0x0000000000685010
然后是一串数字,就是内存映射。
我的程序从 stdin 读取电影及其属性的 CSV 文件并将其标记化。带有逗号的电影标题用引号括起来,所以我将每行分成 3 个标记,并使用逗号作为分隔符再次对前后标记进行标记。我在代码末尾释放了我所有的 malloc,但我仍然收到此错误。扫描 csv 直到结束,但我收到一条错误消息。如果我根本不释放 malloc,我不会收到错误消息,但我非常怀疑它是否正确。这是我的 main() :
char* CSV = (char*)malloc(sizeof(char)*500);
char* fronttoken = (char*)malloc(sizeof(char)*500);
char* token = (char*)malloc(sizeof(char)*500);
char* backtoken = (char*)malloc(sizeof(char)*500);
char* title = (char*)malloc(sizeof(char)*100);
while(fgets(CSV, sizeof(CSV)*500,stdin))
{
fronttoken = strtok(CSV, "\""); //store token until first quote, if no quote, store whole line
title = strtok(NULL,"\""); //store token after first quote until 2nd quote
if(title != NULL) //if quotes in line, consume comma meant to delim title
{
token = strtok(NULL, ","); //eat comma
}
backtoken = strtok(NULL,"\n"); //tokenize from second quote to \n character (remainder of line)
printf("Front : %s\nTitle: %s\nBack: %s\n", fronttoken, title, backtoken); //temp print statement to see front,back,title components
token = strtok(fronttoken, ","); //tokenizing front using comma delim
while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, ",");
}
if (title != NULL) //print if there is a title with comma
{
printf("%s\n",title);
}
token = strtok(backtoken,","); //tokenizing back using comma delim
while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, ",");
}
}
free(CSV);
free(token);
free(fronttoken);
free(backtoken);
free(title);
return 0;
关注这里:
char* title = (char*)malloc(sizeof(char)*100);
title = strtok(NULL,"\"");
- 您动态分配
title
指向的内存。
- 您将
strtok
的 return 值分配给 title
,失去任何
引用使用 malloc()
动态分配的内存!这个
意味着你肯定会发生内存泄漏,因为你会
永远无法取消分配动态分配的内存
之前。
strtok()
的 ref 示例有一个非常有用的示例:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
因此,不需要为 strtok()
return 分配内存 - 正如我之前解释的那样,它实际上很糟糕。
返回您的代码:
free(title);
什么都不做,因为 title
在那个时候是 NULL
(因为 strtok()
.
之后的 while 循环
与token
相同。
此外,fronttoken
和 backtoken
也会导致内存泄漏,因为在 malloc()
之后,它们被分配了 strtok()
的 return 值叫。但是它们的 free()
也有问题(与 title
和 token
的其他取消分配相比),因为它们指向分配给 CSV
.[= 的原始内存中36=]
因此,当调用 free(backtoken);
时,会发生 double-free 或内存损坏。
此外,改变这个:
while(fgets(CSV, sizeof(CSV)*500,stdin))
对此:
while(fgets(CSV, sizeof(*CSV)*500,stdin))
因为你想要 CSV
指向的大小(这是你动态分配的内存的大小)。
我收到此错误:
Error in `./sorter': double free or corruption (!prev): 0x0000000000685010
然后是一串数字,就是内存映射。 我的程序从 stdin 读取电影及其属性的 CSV 文件并将其标记化。带有逗号的电影标题用引号括起来,所以我将每行分成 3 个标记,并使用逗号作为分隔符再次对前后标记进行标记。我在代码末尾释放了我所有的 malloc,但我仍然收到此错误。扫描 csv 直到结束,但我收到一条错误消息。如果我根本不释放 malloc,我不会收到错误消息,但我非常怀疑它是否正确。这是我的 main() :
char* CSV = (char*)malloc(sizeof(char)*500);
char* fronttoken = (char*)malloc(sizeof(char)*500);
char* token = (char*)malloc(sizeof(char)*500);
char* backtoken = (char*)malloc(sizeof(char)*500);
char* title = (char*)malloc(sizeof(char)*100);
while(fgets(CSV, sizeof(CSV)*500,stdin))
{
fronttoken = strtok(CSV, "\""); //store token until first quote, if no quote, store whole line
title = strtok(NULL,"\""); //store token after first quote until 2nd quote
if(title != NULL) //if quotes in line, consume comma meant to delim title
{
token = strtok(NULL, ","); //eat comma
}
backtoken = strtok(NULL,"\n"); //tokenize from second quote to \n character (remainder of line)
printf("Front : %s\nTitle: %s\nBack: %s\n", fronttoken, title, backtoken); //temp print statement to see front,back,title components
token = strtok(fronttoken, ","); //tokenizing front using comma delim
while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, ",");
}
if (title != NULL) //print if there is a title with comma
{
printf("%s\n",title);
}
token = strtok(backtoken,","); //tokenizing back using comma delim
while (token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, ",");
}
}
free(CSV);
free(token);
free(fronttoken);
free(backtoken);
free(title);
return 0;
关注这里:
char* title = (char*)malloc(sizeof(char)*100);
title = strtok(NULL,"\"");
- 您动态分配
title
指向的内存。 - 您将
strtok
的 return 值分配给title
,失去任何 引用使用malloc()
动态分配的内存!这个 意味着你肯定会发生内存泄漏,因为你会 永远无法取消分配动态分配的内存 之前。
strtok()
的 ref 示例有一个非常有用的示例:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
因此,不需要为 strtok()
return 分配内存 - 正如我之前解释的那样,它实际上很糟糕。
返回您的代码:
free(title);
什么都不做,因为 title
在那个时候是 NULL
(因为 strtok()
.
与token
相同。
此外,fronttoken
和 backtoken
也会导致内存泄漏,因为在 malloc()
之后,它们被分配了 strtok()
的 return 值叫。但是它们的 free()
也有问题(与 title
和 token
的其他取消分配相比),因为它们指向分配给 CSV
.[= 的原始内存中36=]
因此,当调用 free(backtoken);
时,会发生 double-free 或内存损坏。
此外,改变这个:
while(fgets(CSV, sizeof(CSV)*500,stdin))
对此:
while(fgets(CSV, sizeof(*CSV)*500,stdin))
因为你想要 CSV
指向的大小(这是你动态分配的内存的大小)。