【问题标题】:*** glibc detected *** outfile: free(): invalid pointer: ****** 检测到 glibc *** 输出文件:free():无效指针:***
【发布时间】:2016-03-27 08:15:30
【问题描述】:

当我释放内存时,它会导致 glibc 检测到错误。 当我给出时它工作正常。(包含单个文件作为输入的当前目录)。 但是 ..(parent directory) 输入给出了这个错误。我尝试使用 gdb 没有成功。 有人可以指出问题。谢谢。 下面是代码。

 /*
*********************************************************************
*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; 
}

【问题讨论】:

  • 关于这一行:if( count &gt;= 2 ) 代码中没有任何内容将 count 设置为除了初始化程序 0 之外的任何内容。代码缺少检查当前目录名称以确保它的语句不是. 也不是..。建议使用 strcmp() 函数将 if( count &gt;= 2 ) 替换为适当的目录名称检查:dp-&gt;d_name。
  • 并非所有文件系统类型都支持 d_type 字段。建议使用stat() 并查看st_mode 字段,使用如下宏:S_ISREG(m) 来确定文件是否为“常规”文件
  • 表达式:sizeof( char ) 被定义为 1。乘以 1 对发送到 malloc() 的参数没有影响,这样的表达式只会使代码混乱,使调试和维护变得更加困难。建议删除该表达式。在调用malloc() 和函数族时,始终检查 (!=NULL) 返回值以确保操作成功。
  • header.h 文件中有什么内容,为什么在同一个文件中包含两次? header.h 有“包含守卫”吗?

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


【解决方案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)) );

【讨论】:

  • 感谢@David_Schwartz 的回复
猜你喜欢
  • 2016-03-28
  • 2013-08-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多