分段故障仅在循环外部

时间:2015-09-01 00:53:59

标签: c linux loops segmentation-fault dynamic-allocation

在Linux上使用C,我正在编写一个代码,使用函数stat()将所有关于文件的信息存储在目录中,并在终端上打印它们 算法非常简单,我制作了一个“文件”结构数组并动态分配它们。该结构包含一个char数组(字符串),所以我也动态分配它。 事情是..动态分配工作正常,但如果我在while循环内,我可以访问结构内部的另一个元素 - 这是一个结构stat对象 - 但如果我在循环结束后访问它,它会给我“分段故障”! 这是代码

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
struct file{
    char* name;
    struct stat fbuf;
};


int main(int argc, char **argv)
{
   char* dir=NULL;
   int k;
   dir=(char *)malloc(strlen(argv[argc-1])+1);
   dir=argv[argc-1];
   strcpy(dir,argv[argc-1]);
   DIR *curr_dir;
   struct dirent *dir_inode;
   int i,j=0;
   char* sum=NULL;
   struct file* files=NULL;
   if ((curr_dir = opendir(dir)) == NULL) {
    fprintf(stderr, "Can't  Open %s\n", argv[1]);
    exit(2);
   }
    while (((dir_inode = readdir(curr_dir))) != NULL) {


    files=(struct file*) realloc(files,((j)+1)*(sizeof(char*)+sizeof(struct stat))); // Structure array reallocation    

    (files+(j))->name=(char *)(malloc(strlen(dir_inode->d_name)+1));//name allocation



    for(i=0;i<strlen(dir_inode->d_name);i++)
        (files+(j))->name[i]=dir_inode->d_name[i];//name storage
    (files+(j))->name[i]='\0';

    sum= (char *) malloc(strlen(dir)+strlen(dir_inode->d_name)+2);//To add file name to its directory

    for(i=0;i<strlen(dir);i++)
        sum[i]=dir[i];

    sum[i]='/';
    i++;
    for(k=0;dir_inode->d_name[k]!='\0';k++)
        sum[i+k]=dir_inode->d_name[k];
    sum[i+k]='\0';//file name with directory in sum


    if( stat(sum,&((files+j)->fbuf)) == -1){ // the function gets information from the file name and stores them in fbuf
        printf("error stat\n");
        exit(1);
    }


    free(sum);
            if(    S_ISDIR(  (  (files+(j))->fbuf  ).st_mode  )    ){
             printf("d");
            }
            else {
               printf("-");
            }
//Here the output appears fine
//The output depends on accessing fbuf in files array
                            printf("statOK\n");
    (j)++; // index
    } 
                            printf("%d %d %d\n",files,j,files+1);



                            printf("%d\n",j);





   printf("\n\n\n\n");
   for(i=0;i<j;i++){
      printf("%s\n",(files+i)->name);
      printf("%d\n",files);
    //Starting from here, same syntax but outside the loop it gives the error
      if(    S_ISDIR(  (  (files+i)->fbuf  ).st_mode  )    ){
         printf("d");

      else {
         printf("-");
      }
}
free(files);
free(dir);
closedir(curr_dir);
exit(1);

}

代码尚未完成,但我想要的只是在循环外访问fbuf,然后我可以完成它 有什么想法吗?

1 个答案:

答案 0 :(得分:2)

不良大小假设

这种分配是错误的:

files=(struct file*) realloc(files,((j)+1)*(sizeof(char*)+sizeof(struct stat)));

在这里,您假设struct file的大小是其两个组件大小的总和。但实际上,您不知道该结构是如何打包和对齐的,因此struct file的大小可能比您想象的要大。您应该只使用sizeof(struct file)

files=(struct file*) realloc(files,(j+1)*(sizeof(struct file)));