c - 为什么在 C 中出现 double free 或 corruption 错误?我释放了我的 mallocs

标签 c string memory-management malloc free

我收到这个错误:

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,"\"");
  1. 动态分配 title 指向的内存。
  2. 您将 strtok 的返回值分配给 title,丢失任何 引用使用 malloc() 动态分配的内存!这 意味着你肯定会发生内存泄漏,因为你会 永远无法取消分配动态分配的内存 之前。

strtok() 的引用示例有一个非常有用的例子:

/* 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() 返回的内容分配内存 - 正如我之前解释的那样,这实际上很糟糕。

回到你的代码:

free(title);

什么都不做,因为 title 在那个时候是 NULL(因为 strtok() 之后的 while 循环。

token 相同。


此外,fronttokenbacktoken也会导致内存泄漏,因为它们在之后被赋予了strtok()的返回值>malloc() 已被调用。但是它们的 free() 也有问题(与 titletoken 的其他取消分配相比),因为它们指向原始为 CSV 分配的内存。

因此,当调用 free(backtoken); 时,会发生双重释放或内存损坏。


此外,改变这个:

while(fgets(CSV, sizeof(CSV)*500,stdin))

为此:

while(fgets(CSV, sizeof(*CSV)*500,stdin))

因为您需要 CSV 指向的大小(即您动态分配的内存大小)。

关于c - 为什么在 C 中出现 double free 或 corruption 错误?我释放了我的 mallocs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46499313/

相关文章:

c - 访问结构数组会出现段错误

C 变量具有不完整的初始值设定项

c - 我的程序不接受使用 getchar 的 c 中的简单字符串

ruby - I18n::InvalidLocaleData:I18n gem 在 js 导出中有问题

c++ - 执行成员函数时对象被删除?

c - 链表——节点的内存地址

ios - 当对象 A 将对象 B 作为属性并且对象 B 有包含对象 A 的数组属性时,Swift 中的保留循环?

c - Stm32时基中断(无需任何库)

c - 这段C代码是否可以编译?

java - 在 Java 中解析字符串