2015-12-21 69 views
1

当我释放内存时,它导致glibc检测到错误。 当我给(当前目录包含单个文件作为输入)时它工作正常。 但是(父目录)输入给出了这个错误。我试图用gdb没有成功。 有人可以指出问题。谢谢。 以下是代码。*** glibc检测到*** outfile:free():无效指针:***

/* 
********************************************************************* 
*File Name - function.c 
Purpose - Implementation of functions like iteration, open_read to 
     printf directories and file properties. 
********************************************************************** 
*/ 

#include "header.h" 


gboolean iterator(GNode* _node, gpointer data) 
{ 
    guint _node_depth = g_node_depth(_node); 

    printf("%p insert _ \t%p data\n",_node,_node->data); 

    if(_node_depth>1) 
    { 
    printf("%.*s",(_node_depth-2)*2,"   "); 
    printf("%s\n",(char *)_node->data); 
    } 
    return SUCCESS; 
} 

gboolean destroyer(GNode* node, gpointer data) 
{ 
    printf("\nfrom destroyer: "); 
    printf("%pnode\t data %p\n",node,node->data); 
    free(node->data); 
    return SUCCESS; 
} 


void open_read(char* input_dir ,GNode* parent) 
{ 
    int count = 0; 
    DIR *dir; 
    struct dirent *dp; 
    char *stat_path = NULL; 
    struct stat file_stat; 
    char *data = NULL; 
    char *formatted_data = NULL; 

    if(NULL == (dir = opendir(input_dir))) 
    { 
    printf("cannot open %s directory",input_dir); 
    } 
    else 
    { 
    /* Loop through directory entries. */ 
    while((dp = readdir(dir)) != NULL) 
    { 
     if(count >= 2) /* omitting '.' and '..' files */ 
     { 
     if(dp->d_type == DT_REG) 
     {  
      /* Get entry's information. */  
      stat_path = (char *)malloc(sizeof(char) * MAX_SIZE); 
      strcpy(stat_path, input_dir); 
      strcat(stat_path, dp->d_name); 

      if (stat(stat_path, &file_stat) == -1) 
      { 
      printf("cant read the stats of %s",dp->d_name); 
      }  
      else 
      { 
      data=(char*)malloc(sizeof(char) * MAX_SIZE); 
      strcpy(data,dp->d_name); 
      strcat(data,"\n\tLinks\tUid\ti_node\tSize\tPath\n"); 
      formatted_data=(char*)malloc(sizeof(char) * MAX_SIZE); 
      sprintf(formatted_data,"\t%d\t%d\t%d\t%d\t%s", (int)file_stat.st_nlink, (int)file_stat.st_uid, (int)file_stat.st_ino, (int)file_stat.st_size,input_dir); 
      strcat(data,formatted_data);  
      //free(formatted_data); 
      g_node_insert(parent,-1,g_node_new(data)); 
      } 
      free(stat_path); 
     } 
     else if(dp->d_type == DT_DIR) 
     { 
      char *sub_dir = (char *)malloc(sizeof(char) * MAX_SIZE); 
      strcpy(sub_dir, input_dir); 
      strcat(sub_dir, dp->d_name); 
      strcat(sub_dir, "/");      
      open_read(sub_dir, g_node_insert(parent,-1,g_node_new(dp->d_name))); 
     } 
     } 
     count++; 
    } 
    } 
    closedir(dir); 
} 


/********************************************************************** 

Purpose   - Simulating the LS command 
Input  - directory path from the command line 
Output  - Displaying the list of directories and file properties 
return  - SUCCESS OR FAILURE 
***********************************************************************/ 

#include "header.h" 
int main(int argc, char* argv[]) 
{ 

    char *user_dir = NULL; 

    /*allocating memory*/ 
    user_dir = (char*)malloc(sizeof(char) * MAX_SIZE); 

    if (NULL == user_dir) 
    { 
    fprintf(stderr, "cant allocate memory..."); 
    return FAILURE; 
    } 

    /*opening and reading the directory by calling open_read()*/ 
    if (argc < 2) 
    { 
    strcpy(user_dir,"./"); 
    } 
    else 
    { 
    strcpy(user_dir, argv[1]); 
    strcat(user_dir, "/"); 
    } 

    GNode * root = g_node_new(user_dir); 
    //g_node_insert(root); 
    open_read(user_dir, root); 
    g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)iterator, NULL); 
    //printf("from main():%s",root->data); 
    g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)destroyer, NULL); 

    g_node_destroy(root); 


    return SUCCESS; 
} 
+0

欢迎堆栈溢出! [请参阅此讨论,为什么不在'C'中投射'malloc()'和family的返回值。](http://stackoverflow.com/q/605845/2173917)。 –

+0

关于这一行:'if(count> = 2)'代码中没有任何内容将count设置为0,但是初始值为0.代码缺少语句来检查当前目录名以确保它是不是''也不'''。建议使用strcmp()函数对目录名称“dp-> d_name”进行适当检查来替换“if(count> = 2)”。 – user3629249

+0

所有文件系统类型都不支持d_type字段。建议使用'stat()'并查看'st_mode'字段,使用如下所示的宏:'S_ISREG(m)'来确定文件是否为'常规'文件 – user3629249

回答

1
char *sub_dir = (char *)malloc(sizeof(char) * MAX_SIZE); 
    strcpy(sub_dir, input_dir); 
    strcat(sub_dir, dp->d_name); 
    strcat(sub_dir, "/");     
    open_read(sub_dir, g_node_insert(parent,-1,g_node_new(dp->d_name))); 

好了,你传递给g_node_new什么什么malloc回来,所以你肯定不能传递到free

gboolean destroyer(GNode* node, gpointer data) 
{ 
    printf("\nfrom destroyer: "); 
    printf("%pnode\t data %p\n",node,node->data); 
    free(node->data); 
    return SUCCESS; 
} 

但你呢!

我相信你想要的结果:

open_read(sub_dir, g_node_insert(parent,-1,g_node_new(sub_dir))); 
+0

谢谢@David_Schwartz的回复 – Tejas