[英]segmentation fault return a string array from a function
I have created a function that creates a dynamic string array with dynamic string length and then I return it to my main function. 我创建了一个函数,创建一个动态字符串数组,动态字符串长度然后我将它返回到我的主函数。 Everything works fine inside my function but when I try to print the array in main I get a segmentation fault after the 4th string - first two string don't print out correct either.
在我的函数中一切正常但是当我尝试在main中打印数组时,我在第4个字符串之后得到了一个分段错误 - 前两个字符串也没有正确打印出来。 This part of the program is supposed to find out all entries in a directory and its sub-directories and store them in main memory.
程序的这一部分应该找出目录及其子目录中的所有条目并将它们存储在主存储器中。
Here's the result: 这是结果:
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
And here's the code: function: 这是代码:功能:
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);
}
main: 主要:
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 is a global variable count是一个全局变量
I just can't figure out what is wrong I think I use the return command properly. 我只是无法弄清楚出了什么问题我认为我正确地使用了return命令。 I also tried the same code with paths as a global variable and it worked fine (main printed out the correct results).
我也尝试使用路径作为全局变量的相同代码,它工作正常(主打印出正确的结果)。 I have a feeling it has something to do with the recursive call of my function
我觉得它与我的函数的递归调用有关
Your problem is that, as per the standard, your realloc
call may (and probably will) return a pointer to a different memory location than the original . 您的问题是, 根据标准,您的
realloc
调用可能(并且可能会)返回指向与原始内存位置不同的内存位置的指针 。
It's a tricky one, and it's a little hard to explain and visualize, but I'll do my best. 这是一个棘手的问题,它有点难以解释和想象,但我会尽我所能。
When you call your function originally, it creates a new stack frame (let's call it A
). 当你最初调用你的函数时,它会创建一个新的堆栈帧(让我们称之为
A
)。 It allocates paths
to an address (say 0x01
), do some stuff with it, then the function calls itself recursively with the paths
address as an argument. 它分配一个地址的
paths
(比如0x01
),用它做一些东西,然后函数以paths
地址作为参数递归地调用它自己。
When you call your function recursively, it creates a new stack frame (let's call it B
), in which you realloc
the paths
pointer - which changes its address from 0x01
to 0x02
- do some stuff with it, and then return it. 当您递归调用你的函数,它会创建一个新的堆栈帧(我们称之为
B
),在您realloc
的paths
指针-这改变了从地址0x01
到0x02
-做一些东西吧,然后返回。
But when B
returns, the paths
pointer in A
still point to the old location, 0x01
, even though it's not valid anymore and has been moved to 0x02
. 但是当
B
返回时, A
的paths
指针仍然指向旧位置0x01
,即使它已经无效并且已经移动到0x02
。
The solution is simple, make sure that you point paths
to the new location when the recursive call ends . 解决方案很简单, 确保在递归调用结束时将
paths
指向新位置 。 So instead of: 所以代替:
getDirContents(tmpName,paths); //Subfolder
...you'd do: ......你做的:
paths = getDirContents(tmpName,paths); //Subfolder
Also, make sure you check the return value of realloc
and malloc
(against NULL
), and don't cast the return value of malloc
. 另外,请确保检查
realloc
和malloc
的返回值(反对NULL
),并且不要malloc
的返回值 。
Your code has an Undefined Behavior . 您的代码具有未定义的行为 。
You call the function as: 您将该函数称为:
A=getDirContents(dir1,NULL);
and the function is defined as: 并且该功能定义为:
char ** getDirContents(char *dirName,char **paths )
Further you call realloc
on paths
. 此外,您在
paths
上调用realloc
。
paths=(char**)realloc(paths,sizeof(char*)*(count+1));
This causes Undefined Behavior. 这会导致未定义的行为。
The standard mandates that the pointer being passed to realloc should exactly match the pointer which was allocated dynamic memory using a memory management function. 标准要求传递给realloc的指针应该与使用内存管理功能分配动态内存的指针完全匹配。 Memory management functions specified by the standard are:
aligned_alloc
, calloc
, malloc
, and realloc
. 标准指定的内存管理函数有:
aligned_alloc
, calloc
, malloc
和realloc
。
The pointer( paths
) you are passing to realloc()
was not returned by any of these and hence the Undefined Behavior. 您传递给
realloc()
的指针( paths
)未被任何这些指针( paths
)返回,因此未返回未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.