2014-12-03 52 views
0

我正在使用Linux的list.h APIs,并想知道我是否有内存泄漏。 原因是在代码的一部分为每个循环分配不同的内存地址(第40-41行),但从第56-57行返回的地址:cmd = list_entry(...)是最后一个malloc-ed地址。是免费的(cmd_ptr); list_del_init(& cmd_head);够好了?如何避免使用Linux list.h API的内存泄漏

注意:注意

cmd = list_entry(pos, struct cmd_buf, list); 
printf("entry ptr: %p\n", cmd_ptr); 

被返回同一地址。代码后请参阅屏幕输出。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "list.h" // locally copied to working dir 
// original http://lxr.free-electrons.com/source/include/linux/list.h 

#define DEFAULT_SCRIPT_FILE "commands.txt" 
#define BUFSIZE 256 

typedef struct cmd_buf { 
    char buf[BUFSIZE]; 
    struct list_head list; 
} Cmd_buf; 

int main(int argc, char *argv[]) 
{ 
    script_xxx(); 
    return 0; 
} 

int script_xxx(void) 
{ 
    FILE *pfile = 0; 
    char file_name[BUFSIZE], tmp_buf[BUFSIZE]; 
    struct list_head cmd_head, *pos = 0; 
    Cmd_buf *cmd_ptr, *cmd; 
    int i = 0, max_loops = 3; 

    strncpy(file_name, DEFAULT_SCRIPT_FILE, sizeof(file_name)); 
    pfile = fopen(file_name, "r"); 
    if(pfile == NULL) { 
      printf("Failed to open file %s\n", file_name); 
      return -1; 
    } 

    INIT_LIST_HEAD(&cmd_head); 

    while (!feof(pfile)) { 
      if(fgets(tmp_buf, BUFSIZE, pfile)) { 
       cmd_ptr = malloc(sizeof(Cmd_buf)); 
       printf("malloc ptr: %p\n", cmd_ptr); 
       strncpy(cmd_ptr->buf, tmp_buf, sizeof(tmp_buf)); 
       list_add_tail(&(cmd_ptr->list), &cmd_head); 
      } 
    } 
    fclose(pfile); 

    if(list_empty(&cmd_head)) { 
     printf("Command not found in %s\n", file_name); 
     return 0; 
    } 

    for (i = 0; i < max_loops; i++) { 
     printf("\n\nRunning commands loop %d\n", i); 
     list_for_each(pos, &(cmd_head)) { 
      cmd = list_entry(pos, struct cmd_buf, list); 
      printf("entry ptr: %p\n", cmd_ptr); 
      if(cmd) printf(" Runing cmd in loop %d: %s", i, cmd->buf); 
     } 
    } 

    if(i == max_loops) 
     printf("\nCompleted all %d loops\n", i); 
    else if(i < max_loops) 
     printf("\nCommand failed at loop %d\n", i); 

    if(cmd_ptr) free(cmd_ptr); 
    list_del_init(&cmd_head); 
    printf("freeing ptr: %p\n", cmd_ptr); 
    return 0; 
} 




./a.out 
malloc ptr: 0x2df8250 
malloc ptr: 0x2df8370 
malloc ptr: 0x2df8490 


Running commands loop 0 
entry ptr: 0x2df8490 
    Runing cmd in loop 0: command a b c 
entry ptr: 0x2df8490 
    Runing cmd in loop 0: command x y z 
entry ptr: 0x2df8490 
    Runing cmd in loop 0: command yyy 


Running commands loop 1 
entry ptr: 0x2df8490 
    Runing cmd in loop 1: command a b c 
entry ptr: 0x2df8490 
    Runing cmd in loop 1: command x y z 
entry ptr: 0x2df8490 
    Runing cmd in loop 1: command yyy 


Running commands loop 2 
entry ptr: 0x2df8490 
    Runing cmd in loop 2: command a b c 
entry ptr: 0x2df8490 
    Runing cmd in loop 2: command x y z 
entry ptr: 0x2df8490 


Completed all 3 loops 
freeing ptr: 0x935490 

回答

1
  1. 使用 '的valgrind your_program' 来检查是否有内存泄露。

  2. INIT_DLIST_HEAD()??应该是INIT_LIST_HEAD()吗?

  3. 在您的程序中,cmd_ptr是指向cmd_buf的指针,仅用于插入循环。最后不需要释放cmd_ptr,因为它指向的对象已被插入到列表中。它应该与列表中的其他对象一起被释放。

  4. 您应该使用循环来迭代地释放列表中的对象。 例如:(!list_empty(cmd_head))

    而{
    CMD = list_next_entry(cmd_head,列表);
    __list_del_entry(& cmd-> list);
    free(cmd); }