0

I have following code which will print all the filenames from a given directory. But error is Segmentation fault (core dumped). I am not experienced using strcpy with pointers.

skipping include

extern int errno;

typedef struct fileinfo
{
char filename[256];
off_t filesize;
time_t mtime;
} FILE_INFO;

int main(int argc, char **argv) {

DIR *dir;
struct dirent *d_ent;
FILE_INFO **file_info;
int i = 0, j = 1;

if((dir = opendir("/")) ==NULL) goto err;

file_info = (FILE_INFO **)malloc(sizeof(FILE_INFO *) * j);

while((d_ent = readdir(dir)) != NULL)
{
    file_info = (FILE_INFO **)realloc(file_info,sizeof(FILE_INFO *) * j);
    strcpy(file_info[j]->filename, d_ent->d_name); //Error here Segmentation fault (core dumped)

    j++;
}

for( i =0 ; i > j; i++)
{
    printf("%s\n", file_info[i]->filename);
}

free(file_info);
return 0;
err:
printf("Error is : %d : %s", errno, strerror(errno));
return 0;
}
Haris
  • 12,120
  • 6
  • 43
  • 70
pmverma
  • 1,653
  • 13
  • 27
  • 3
    [Please don't cast the return value of `malloc()` and friends, in C](http://stackoverflow.com/a/605858/28169). – unwind Dec 10 '13 at 12:05

3 Answers3

1

Note: there might be other issues, but the line you suggested has below problem.

When you are allocating for j elements, the last item is accessed at j-1, so update your line as

//----------------v
strcpy(file_info[j-1]->filename, d_ent->d_name);

instead of

strcpy(file_info[j]->filename, d_ent->d_name);

Also, instead of using FILE_INFO ** you should use FILE_INFO *file_info; (and update other code accordingly).

Rohan
  • 52,392
  • 12
  • 90
  • 87
0

You have to allocate space for the filename first.

file_info[j]->filename=malloc(strlen(d_ent->d_name)+1);
strcpy(file_info[j]->filename, d_ent->d_name);

or use the strdup function that's made for this kind of stuff:

file_info[j]->filename=strdup(d_ent->d_name);

Unrelated, but another bug in your code:

for( i =0 ; i > j; i++)

should read

for( i =0 ; i < j-1; i++)

It would be much better/easier to initialize j=0, however.

Guntram Blohm
  • 9,667
  • 2
  • 24
  • 31
  • Did you just edit "char *filename" to "char filename[256]"? When the filename is an array, you don't have to use strdup of course. Rohans answer is correct though, remember C arrays start with index 0. – Guntram Blohm Dec 10 '13 at 12:01
  • @Guntran Bohm incompatible types when assigning to type ‘char[256]’ from type ‘char *’ – pmverma Dec 10 '13 at 12:08
  • See my 1st comment to my answer: if you declare char filename[256] instead of char *filename, you're ok in this. The bug is your `j` indexing out of the array. My first answer was more or less automatic, since so many people make the same mistake; i didn't see it doesn't apply to you. – Guntram Blohm Dec 10 '13 at 12:10
0

In addition to other answers, files in linux are not up to 255 chars long. max is 4095. It could be that there's a buffer overflow when writing to file_info[j]->filename. Declare file_info[j]->filenameas a char* and call strdup() on the source string to duplicate it.

egur
  • 7,830
  • 2
  • 27
  • 47