C 尝试在内存中构建目录树时出现指针问题

C 尝试在内存中构建目录树时出现指针问题,c,linux,unix,tree,C,Linux,Unix,Tree,问题1:保存目录结构的最佳数据结构是什么 问题2:我尝试使用通用树来解决它,但有很多问题: 目录下的文件数不确定。因此,树节点下的子节点数量也不确定。我尝试向每个节点添加关键字nchild,显示nchild子节点。因此,存在指向子节点的nchild指针(与**子节点一起保存)。一旦这样,**子节点和*子节点就应该动态分配空间,而不需要特定的子节点。所以你知道,释放这些空间非常困难(下面的程序不是free())。有没有更好的办法解决这个问题 有时候,当我输出目录树时,下面的程序会得到垃圾字符,这

问题1:保存目录结构的最佳数据结构是什么

问题2:我尝试使用通用树来解决它,但有很多问题:

  • 目录下的文件数不确定。因此,树节点下的子节点数量也不确定。我尝试向每个节点添加关键字
    nchild
    ,显示
    nchild
    子节点。因此,存在指向子节点的
    nchild
    指针(与
    **子节点一起保存)。一旦这样,
    **子节点
    *子节点
    就应该动态分配空间,而不需要特定的子节点。所以你知道,释放这些空间非常困难(下面的程序不是
    free()
    )。有没有更好的办法解决这个问题
  • 有时候,当我输出
    目录树时,下面的程序会得到垃圾字符,这让我很困惑。调试时发现是函数
    ent=readdir(pDir)已读取垃圾字符。但是,当我编写另一个简单的程序来读取同一个目录时,情况很好。我认为问题在于递归函数,但我不知道。如果有人能给我一个主意,我将不胜感激。谢谢
    
```

#包括
#包括
#包括
#包括
#包括
#包括
#包括
typedef结构树文件
{
字符路径[512];
时间和日期;
煤焦类型;
长尺寸;
int nchild;
结构树文件**子级;
}树文件;
int dir_child_len(const char*dir)
{
int-nchild=0;
DIR*pDir;
结构导向;
pDir=opendir(dir);
while((ent=readdir(pDir))!=NULL)
{
如果(strcmp(ent->d_name,“.”)=0 | | strcmp(ent->d_name,“…”)==0)
{
继续;
}
nchild++;
}
返回nchild;
}
void tree\u create(tree\u file\u t*tft,const char*dir)
{
int nchild;//tft有n个子项
DIR*pDir;
struct dirent*ent;//目录dirent-info
struct stat file_stat;//新文件的stat info
统计(目录和文件统计);
nchild=目录子目录(目录);
pDir=opendir(dir);
//初始化父级
//tft->path=calloc(1,strlen(dir)+1);
strcpy(tft->path,dir);
tft->date=文件\u stat.st\u mtime;
tft->type='D';
tft->size=file\u stat.st\u size;
tft->nchild=nchild;
tft->child=calloc(1,nchild);
nchild=0;
while((ent=readdir(pDir))!=NULL)
{
if(ent->d_类型和DT_目录)
{
如果(strcmp(ent->d_name,“.”)=0 | | strcmp(ent->d_name,“…”)==0)
{
继续;
}
tree_file_t*new_dir=calloc(1,sizeof(tree_file_t));
tft->child[nchild]=新目录;
char*new_path=calloc(1,strlen(dir)+strlen(ent->d_name)+1);
sprintf(新路径,“%s/%s”,目录,ent->d_名称);
树创建(新目录,新路径);
免费(新路);
}否则{
tree_file_t*new_file=calloc(1,sizeof(tree_file_t));
char*new_path=calloc(1,strlen(dir)+strlen(ent->d_name)+1);
//新建文件->路径=calloc(1,strlen(dir)+strlen(ent->d_name)+1);
sprintf(新路径,“%s/%s”,目录,ent->d_名称);
stat(新路径和文件统计);
strcpy(新建文件->路径,新建路径);
免费(新路);
新建文件->日期=文件\u stat.st\u mtime;
新建_文件->类型='F';
新建文件->大小=文件\u stat.st\u大小;
新建文件->nchild=0;
新建文件->子文件=0;
tft->child[nchild]=新的\u文件;
}
//免费(新路);
//新路径=0;
nchild++;
}
}
无效显示树(树文件*tft)
{
在中国,我;
nchild=tft->nchild;
printf(“%c:%s\n”,tft->type,tft->path);
对于(i=0;ichild[i]->type=='F')
{
printf(“%c:%s\n”,tft->child[i]->type,tft->child[i]->path);
}否则{
显示_树(tft->child[i]);
}
}
}
int main(int argc,const char*argv[]
{
如果(argc!=2)
{
printf(“用法:a.out dir\n”);
出口(0);
}
char-dir[512];
strcpy(dir,argv[1]);
tree_file_t*tft=calloc(1,sizeof(tree_file_t));
树创建(tft,dir);
显示树(tft);
返回0;
}

```

新路径分配空间时,需要添加2个(一个用于斜杠,一个用于空终止符)。而且您从不关闭打开的目录(使用closedir()

更严重的错误是这一行:

tft->child = calloc(1, nchild);
它只分配nchild字节,不足以容纳nchild指针!尝试:

tft->child = calloc(nchild, sizeof(*tft->child));

是的,谢谢你的回答。但当我试图修改这两个地方时<代码>损坏的双链接列表:
发生在
closedir(pDir)处@xuefu,表示堆已损坏。我注意到另一个错误(可能是原因)。请参见上面的编辑。它不应该是
calloc(nchild,sizeof(struct tree\u file.*))
(一颗星)。也许更好
calloc(nchild,sizeof(*tft->child))
@chux-Yep。固定的。谢谢。@xuefu:是的-你会追踪你所做的每一次分配,释放所有依赖的分配,然后释放分配的空间。这需要一些小心。对于您进行的每个分配,计算出相应的
free()
发生的位置。
tft->child = calloc(nchild, sizeof(*tft->child));