2012-03-11 76 views
0

我创建了一个函数,它创建一个动态字符串长度的动态字符串数组,然后将其返回到我的主函数。一切工作正常我的函数内,但是当我尝试在主要打印数组时,我得到第四个字符串后的分段错误 - 前两个字符串不打印出正确的。程序的这部分应该找出目录及其子目录中的所有条目并将它们存储在主内存中。段错误从函数返回字符串数组

这里的结果:

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]); 
} 

计数是一个全局变量

我只是无法弄清楚什么是错误的,我想我正确地使用了返回命令。我也尝试了与路径相同的代码作为全局变量,并且它工作正常(主要打印出正确的结果)。 我有一种感觉它是与我的函数的递归调用

+3

请把它归结为一个简单的测试用例(不超过10-15行)。请参阅http://sscce.org。 – 2012-03-11 16:16:32

+1

嗯,找到它。这真的是我的功能 recudive电话我改变了这个:getDirContents(tmpName,paths); //子文件夹: paths = getDirContents(tmpName,paths); //子文件夹 它现在正常工作 – 2012-03-11 16:18:58

+0

什么是count ',全球? – phoxis 2012-03-11 16:19:36

回答

1

你的代码中有一个未定义行为

你调用该函数为:

A=getDirContents(dir1,NULL); 

和函数定义为:

char ** getDirContents(char *dirName,char **paths) 

而且你打电话pathsrealloc

paths=(char**)realloc(paths,sizeof(char*)*(count+1)); 

这会导致未定义的行为。

标准要求传递给realloc的指针应该与使用内存管理函数分配动态内存的指针完全匹配。该标准规定的存储器管理功能是: aligned_alloc,calloc,mallocrealloc

您传递给realloc()的指针(paths)未被任何这些返回,因此未定义的行为。

+0

我不明白为什么它是不确定的,我改变了这个 getDirContents(tmpName,路径); //子文件夹 为路径= getDirContents(tmpName,路径); //子文件夹 它仍然是不确定的行为?来自主要问题的调用中的NULL参数?调用路径上的realloc有什么问题? – 2012-03-11 21:59:35

+0

哦,我想我明白了你的意思 – 2012-03-11 22:04:51

+2

等等,什么?用'NULL'指针调用'realloc'是明确定义的行为:C11,7.22.3.5/3,*“如果'ptr'是一个空指针,'realloc'函数的行为与 的'malloc'函数指定的大小。“* – netcoder 2013-01-14 20:40:58

1

您的问题是,按照标准,你realloc通话可能(可能会)返回一个指向不同的内存位置比原来的

这是一个棘手的问题,这有点难以解释和可视化,但我会尽我所能。

当你最初调用你的函数时,它会创建一个新的栈帧(我们称之为A)。它将paths分配给一个地址(比如0x01),用它做一些事情,然后该函数以paths地址作为参数递归地调用它自己。

当你打电话给你的函数递归,它会创建一个新的堆栈帧(姑且称之为B),在其中reallocpaths指针 - 这改变从0x010x02其地址 - 做一些东西吧,然后返回它。

但当B返回时,paths指针A仍然指向旧的位置,0x01,即使它不再有效,并已被转移到0x02

解决方案很简单,确保当递归调用结束时您指向paths到新位置。因此,而不是:

getDirContents(tmpName,paths); //Subfolder 

...你会怎么做:

paths = getDirContents(tmpName,paths); //Subfolder 

此外,请务必检查的reallocmalloc(对NULL)的返回值,并don't cast the return value of malloc