Как освободить выделенную память в этом блоке кода C? - PullRequest
0 голосов
/ 06 марта 2019

Я запускаю valgrind для своего кода, и это показывает, что я не освободил свою память, когда использовал malloc. Я пытался освободить его, но он дает мне то же самое сообщение. Любые предложения о том, как это может быть исправлено?

Спасибо!

/** 
* Read all the words from the given file, an return them as a
* linked list.
*/
Node *readWords( char *filename )
{
    FILE *fp = fopen( filename, "r" );

    if ( !fp ) {
        fprintf( stderr, "Can't open file: %s\n", filename );
        usage();
    }

    Node *list = NULL;

    while ( true ) {
        int ch = fgetc( fp );

        while ( ch != EOF && ! wordChar( ch ) )
            ch = fgetc( fp );

        Node *n = (Node *) malloc( sizeof( Node ) );

        int len = 0;
        while ( wordChar( ch ) ) {
            if ( len < WORD_MAX )
                n->word[ len++ ] = toLower( ch );

            ch = fgetc( fp );
        }

        n->word[ len ] = '\0';

        if ( len == 0 ) {
           return list;
        }

        n->next = list;

        list = n;

        free(n);
    }

    fclose(fp);
}

int main( int argc, char *argv[] )
{
  if ( argc != 2 )
    usage();

  Node *list = readWords( argv[ 1 ] );
  list = sortList( list );

  reportWords( list );

  while (list) {

     Node *next = list->next;
     free( list );
       list = next;
  }
return EXIT_SUCCESS;
}

Вот часть, где я освобождаю узлы после того, как использую их в списке.

/** Insertion sort on a linked list. */
Node *sortList( Node *list )
{
  Node *newList = NULL;

  while ( list ) {

    Node *n = list;
    list = list->next;

    Node **target = &newList;
    while ( *target && strcmp( n->word, (*target)->word ) >= 0 )
      target = &(*target)->next;

    n->next = *target;
    *target = n;
  }

  return newList;
}

Вот часть, где она сортируется.

/** Given a sorted list, report the number of occurrences of each word. */
void reportWords( Node *list )
{
  Node *n = list;
  while ( n ) {
    Node *end = n->next;
    int ocount = 0;
    while ( end && strcmp( n->word, end->word ) == 0 ) {
      end = end->next;
      ocount++;
    }
    printf( "%s (%d)\n", n->word, ocount );
    n = end;
  }
}

Вот функция, которая сообщает о словах (печатает их).

1 Ответ

2 голосов
/ 06 марта 2019

У вас есть две основные проблемы, обе в readWords:

while ( true ) {
    ...
    Node *n = (Node *) malloc( sizeof( Node ) );
    ...

    if ( len == 0 ) {
       return list;
    }

    n->next = list;

    list = n;

    free(n);
}

fclose(fp);

Вы заполняете узел, добавляете этот узел в список, а затем немедленно освобождаете этот узел, делая его недействительным.Позже, когда вы пытаетесь прочитать список, вы вызвали неопределенное поведение , разыменовав указатель на память, которая уже была освобождена.Вы уже освобождаете список в конце main, поэтому нет необходимости делать это здесь.

Это оставляет вас с парой утечек памяти.Когда вы достигнете конца файла, проверка len == 0 верна, поэтому вы сразу же вернетесь из функции.Это оставляет самый последний узел, который вы выделили (который ничего не содержит), как утечку, и вы не закрываете fp.Это можно исправить, освободив n внутри блока if и используя break для выхода из цикла, и переместив оператор return после fclose.

while ( true ) {
    ...
    Node *n = (Node *) malloc( sizeof( Node ) );
    ...

    if ( len == 0 ) {
        free(n);
        break;
    }

    n->next = list;
    list = n;
}

fclose(fp);
return list;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...