我在代码上运行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;
}
}
这是报告单词(打印出来)的功能。
答案 0 :(得分:2)
您在readWords
中遇到了两个主要问题:
while ( true ) {
...
Node *n = (Node *) malloc( sizeof( Node ) );
...
if ( len == 0 ) {
return list;
}
n->next = list;
list = n;
free(n);
}
fclose(fp);
您填充一个节点,将该节点添加到列表中,然后立即释放该节点以使其无效。稍后,当您尝试读取列表时,通过取消引用指向已释放内存的指针来调用undefined behavior。您已经在main
的末尾释放列表,因此无需在此处进行操作。
这会留下一些悬而未决的内存泄漏。当到达文件末尾时,len == 0
检查为true,因此您立即从函数中返回。这会将您分配的最新节点(不包含任何内容)留为泄漏,并且您不会关闭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;