glibc检测到outfile:free():指针无效:

时间:2015-12-22 03:38:32

标签: c memory-management memory-leaks free glibc

我的代码给出了glibc错误。有人请指出我的错误。    此代码用于标记单词。如何使用GDB或任何其他有用的工具解决这些问题。代码如下:

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

struct token
{
  char *token;
  int length;   
};

void freeing(gpointer item) 
{
 free(((struct token*)item)->token);
 }


int main(int argc, char* argv[])
{
     int start1 = 0, start2 = 0, i =0;

     struct token *tk = NULL;
     char line[256], *temp = NULL;

     FILE *fp1 = NULL;
     FILE *fp2 = NULL;

     GSList *list = NULL, *iterator = NULL;
     fp1 = fopen(argv[1], "r");
     fp2 = fopen(argv[2], "w+");

     if (NULL == fp1)
    {
       fprintf(stderr,"cant open %s",argv[1]);
        return 1;
    }

   if (NULL == fp2)
   {
      fprintf(stderr,"cant open %s",argv[2]);
      return 1;
   }    

  while (1)
  { 

   if (NULL == fgets(line, 255, fp1))
     break;

   tk = (struct token *)malloc(sizeof(struct token));

   start1 = -1; start2 = -1;

  for(temp = line,i = 0; temp[i] != '\n'; i++)
  {
      if ((temp[i] == ',')  || (temp[i] == ' ') || (temp[i] == ';') || (temp[i] == '.'))
         start2 = i;

      if (start1 == start2)
        continue;



    tk->token = strndup(line + (start1+1), start2 - (start1+1));
    tk->length = strlen(tk->token);
    list = g_slist_append(list, tk);

    start1 = start2;    

  }

    tk->token = strndup(line + (start1+1), strlen(line));
    tk->length = strlen(tk->token);
    printf("\ntk->length : %d\n",tk->length);
    list = g_slist_append(list, tk );


 }


  for (iterator = list;  iterator; iterator = iterator->next)
  {
    printf("%s -> ",((struct token *)(iterator->data))->token);
    printf("%d\n",((struct token*)iterator->data)->length);
  }

  g_slist_foreach(list, (GFunc)freeing, NULL);

 fclose(fp1);
 fclose(fp2);

return 0;

}

1 个答案:

答案 0 :(得分:1)

以下代码修复了主要问题,但没有修复循环中的逻辑错误:

for(int i=0, temp = line; temp[i] != '\n'; i++)
{
    ...
}

tk->token = strndup(line + (start1+1), strlen(line));
tk->length = strlen(tk->token);
printf("\ntk->length : %d\n",tk->length);
list = g_slist_append(list, tk );

以下针对发布代码中的大多数问题的建议修正更正:

添加了对g_slist_free(list);的最终调用,因此struct token的所有实例都返回到堆中。

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>

#define MAX_LINE_LEN (256)

struct token
{
    char *token;
    int length;
};

void freeing(gpointer item)
{
    free(((struct token*)item)->token);
}


int main(int argc, char* argv[])
{
    if( 3 != argc )
    { // then incorrect number of command line arguments
        fprintf( stderr, "USAGE: %s <inputfile> <outputfile>\n", argv[0]);
        exit( EXIT_FAILURE );
    }

    // implied else, correct number of command line arguments

    FILE *fp1 = NULL;
    FILE *fp2 = NULL;

    if( NULL == (fp1 = fopen(argv[1], "r") ) )
    { // then fopen failed
        fprintf( stderr, "fopen for %s for read failed\n", argv[1]);
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    if( NULL == (fp2 = fopen(argv[2], "w+") ) )
    { // then fopen failed
        fprintf( stderr, "fopen for %s for write failed\n", argv[2]);
        fclose( fp1 ); // cleanup
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful



    GSList *list = NULL;
    GSList *iterator = NULL;

    char line[ MAX_LINE_LEN ];
    struct token *tk = NULL;
    char *temp = NULL;

    while ( fgets(line, sizeof(line), fp1) )
    {

        if( NULL == (tk = malloc(sizeof(struct token)) ) )
        { // then malloc failed
            perror( "malloc for struct token failed");
            fclose( fp1 );
            fclose( fp2 );
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful

        size_t start1 = 0;
        size_t start2 = 0;

        temp = line;
        for(size_t i=0; temp[i] != '\n'; i++)
        {
            if ((temp[i] == ',')  || (temp[i] == ' ') || (temp[i] == ';') || (temp[i] == '.'))
                start2 = i;

            if (start1 == start2)
                continue;

            tk->token = strndup(line + (start1+1), start2 - (start1+1));
            tk->length = (int)strlen(tk->token);
            list = g_slist_append(list, tk);

            start1 = start2;
        } // end for

        tk->token = strndup(line + (start1+1), strlen(line));
        tk->length = (int)strlen(tk->token);
        printf("\ntk->length : %d\n",tk->length);
        list = g_slist_append(list, tk );

    } // end while


    for (iterator = list;  iterator; iterator = iterator->next)
    {
        printf("%s -> ",((struct token *)(iterator->data))->token);
        printf("%d\n",((struct token*)iterator->data)->length);
    }

    g_slist_foreach(list, (GFunc)freeing, NULL);
    g_slist_free(list);

    fclose(fp1);
    fclose(fp2);

    return 0;

}