为什么在C中双重释放或损坏错误?我释放了我的mallocs

时间:2017-09-30 03:29:13

标签: c string memory-management malloc free

我收到此错误:

  

`./orter'错误:双重免费或损坏(!prev):0x0000000000685010

然后是一堆数字,这是内存映射。 我的程序从stdin中读取电影及其属性的CSV文件并对其进行标记。带有逗号的电影的标题用引号括起来,所以我将每一行分成3个标记,并使用逗号作为分隔符再次标记前后标记。我在代码的末尾释放了所有的malloc,但我仍然得到这个错误。扫描csv直到结束,但我收到错误消息。如果我根本没有释放mallocs,我就不会收到错误消息,但我非常怀疑它是对的。这是我的主要():

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;

1 个答案:

答案 0 :(得分:1)

关注点:

char* title = (char*)malloc(sizeof(char)*100);
title = strtok(NULL,"\"");
  1. 您可以动态分配title指向的内存。
  2. 您将strtok的返回值分配给title,失去任何值 引用用malloc()动态分配的内存!这个 意味着你将定义一个内存泄漏,因为你会 永远无法取消分配动态分配的内存 之前。
  3. ref 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);
    

    不执行任何操作,因为此时titleNULL(因为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指向的大小(即动态分配的内存大小)。