2015-09-01 2 views
1

Использование C на Linux, я пишу код, который хранит всю информацию о файлах в каталоге, используя функцию stat() и печатает их на терминале . Алгоритм довольно прост, я создал структурный массив «файлов» и динамически выделил их. Структура содержит массив символов (string), поэтому я также динамически выделял его. Дело в том, что динамическое распределение работает нормально, но если я внутри цикла 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 вне цикла, то я могу закончить это идеи?

+0

'STRCPY (реж, ARGV [ARGC-1])' необходимо изменить в 'реж = ARGV [ARGC-1]', так как реж куча выделяется указатель – stackptr

+0

Изменен. Еще одна ошибка:/ –

+1

Исправьте форматирование кода. На данный момент невозможно прочитать. Но что еще более важно, в конце кода отсутствуют отсутствующие замыкающие скобки. Размещение этих закрывающих скобок может быть или не быть значительным. – kaylum

ответ

2

Bad размер предположение

Это распределение является неправильным:

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))); 
Смежные вопросы