我创建了一个创建动态字符串数组的函数,然后将其返回给我的main函数。在我的函数中一切正常但是当我尝试在main中打印数组时,我在第4个字符串之后得到了一个分段错误 - 前两个字符串也没有正确打印出来。程序的这一部分应该找出目录及其子目录中的所有条目,并将它们存储在主存储器中。
结果如下:
Path[0]=A/New Folder. - i=0
Path[1]=A/atext - i=1
Path[2]=A/a - i=2
Path[3]=A/alink - i=3
Path[4]=A/afolder - i=4
Path[5]=A/afolder/set008.pdf - i=0
Path[6]=A/afolder/anotherfolder - i=1
Path[7]=A/afolder/anotherfolder/folderOfAnotherFolder - i=0
Path[8]=A/afolder/anotherfolder/folderOfAnotherFolder/mytext - i=0
Path[9]=A/afolder/anotherfolder/mytext - i=1
Path[10]=A/afolder/set001.pdf - i=2
Entries in directory: A
��
��
A/a
A/alink
Segmentation fault
这是代码: 功能:
char ** getDirContents(char *dirName,char **paths )
{
DIR * tmpDir;
struct dirent * entry;
//char tmpName[512];
char * tmpName=NULL;
struct stat node;
int size=0;
int i=0;
//paths=NULL;
if((tmpDir=opendir(dirName))==NULL){
perror("getDirContents opendir");
return NULL;
}
i=0;
while ((entry=readdir(tmpDir))!=NULL)
{
//if (entry->d_ino==0) continue;
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)//Ignore root & parent directories
continue;but I
tmpName =(char *)malloc(strlen(dirName)+strlen(entry->d_name)+2);
strcpy(tmpName,dirName);
strcat(tmpName,"/");
strcat(tmpName,entry->d_name);
//printf("\ntmpName[%d]:%s",count,tmpName);
paths=(char**)realloc(paths,sizeof(char*)*(count+1));
paths[count]=NULL;
//paths[count]=(char*)realloc(paths[count],strlen(tmpName)+1);
paths[count]=(char*)malloc(strlen(tmpName)+1);
//memcpy(paths[count],tmpName,strlen(tmpName)+1);
strcpy(paths[count],tmpName);
printf("\nPath[%d]=%s - i=%d",count,paths[count],i);
count++;
if(lstat(tmpName,&node)<0)
{
printf("\ntmpName:%s",tmpName);
perror("getDirContents Stat");
exit(0);
}
if (S_ISDIR(node.st_mode))
{
getDirContents(tmpName,paths);//Subfolder
}
//printf("\n%s,iters:%d",tmpName,i);
free(tmpName);
tmpName=NULL;
i++;
}
close(tmpDir);
return(paths);
}
主:
char **A=NULL;
count=0;
A=getDirContents(dir1,NULL);
Aentries=count;
count=0;
//B=getDirContents(dir2,NULL);
printf("\nEntries in directory: %s",dir1);
for(i=0;i<Aentries;i++)
{
printf("\n%s",A[i]);
}
count是一个全局变量
我无法弄清楚出了什么问题我认为我正确地使用了return命令。我也尝试使用路径作为全局变量的相同代码,它工作正常(主打印出正确的结果)。 我觉得它与我的函数的递归调用有关
答案 0 :(得分:1)
您的代码有未定义的行为。
您将该功能称为:
A=getDirContents(dir1,NULL);
,该函数定义为:
char ** getDirContents(char *dirName,char **paths )
再次致电realloc
paths
。
paths=(char**)realloc(paths,sizeof(char*)*(count+1));
这会导致未定义的行为。
标准要求传递给realloc的指针应该与使用内存管理功能分配动态内存的指针完全匹配。标准规定的内存管理功能包括:
aligned_alloc
,calloc
,malloc
和realloc
。
您传递给paths
的指针(realloc()
)未被其中任何一个返回,因此未返回未定义的行为。
答案 1 :(得分:1)
您的问题是,根据标准,您的realloc
调用可能(并且可能会)返回指向与原始不同的内存位置的指针。
这是一个棘手的问题,它有点难以解释和想象,但我会尽我所能。
当你最初调用你的函数时,它会创建一个新的堆栈帧(让我们称之为A
)。它将paths
分配给一个地址(比如0x01
),用它做一些事情,然后函数以paths
地址作为参数递归调用自身。
当你以递归方式调用函数时,它会创建一个新的堆栈帧(让我们称之为B
),在其中realloc
paths
指针 - 从{{{}更改其地址1}}到0x01
- 用它做一些东西,然后返回它。
但是当0x02
返回时,B
中的paths
指针仍然指向旧位置A
,即使它已经无效并且已移至0x01
{1}}。
解决方案很简单,确保在递归调用结束时将0x02
指向新位置。所以而不是:
paths
...你会这样做:
getDirContents(tmpName,paths); //Subfolder
另外,请务必检查paths = getDirContents(tmpName,paths); //Subfolder
和realloc
(针对malloc
)和don't cast the return value of malloc
的返回值。