1
\$\begingroup\$

I want to fill an array of dirent pointers with each entry of a specified directory. I either need to count the items before, allocate memory, then go over them again, or I will have to reallocate each iteration of the while loop. Both of these options seem slow. Surely there's a better way.

Are these my only option:

struct dirent **Entries;
DIR *Dir = opendir("Some dir path");
struct dirent *Entry;
unsigned int Count = 0;
while ((Entry = readdir(Dir))) {
    Count++;
}
Entries = malloc(Count*sizeof(struct dirent*));
rewinddir(Dir);
for (int i = 0; (Entry = readdir(Dir); i++) {
    Entries[i] = Entry;
}

Or

struct dirent **Entries;
DIR *Dir = opendir("Some dir path");
Dir = opendir("Some dir path");
struct dirent *Entry;
for (int i = 0; (Entry = readdir(Dir); i++) {
    Entries = realloc(Entries, i*sizeof(struct dirent*));
    Entries[i] = Entry;
}
closedir(Dir);

Or is there some faster way?

\$\endgroup\$
11
  • \$\begingroup\$ C and the standard C library have no ways to read a directory. Fastest way is implementation dependent - if it exists. I recommend to add a tag to the implementation used. \$\endgroup\$ – chux - Reinstate Monica Jun 15 '20 at 23:09
  • \$\begingroup\$ @chux-ReinstateMonica But surely there's a cross platform way? \$\endgroup\$ – user220256 Jun 15 '20 at 23:11
  • 1
    \$\begingroup\$ We could provide better suggestions if you included more of the code rather than just snippets. \$\endgroup\$ – pacmaninbw Jun 16 '20 at 0:08
  • 1
    \$\begingroup\$ Please do not edit the code after an answer has been posted. The code that everyone sees should be the same. \$\endgroup\$ – pacmaninbw Jun 16 '20 at 0:26
  • 1
    \$\begingroup\$ It was observed by the person that wrote the review, and the rules are clear that code should not be edited after an answer has been posted. \$\endgroup\$ – pacmaninbw Jun 16 '20 at 0:30
1
\$\begingroup\$

OP poses 2 approaches

  1. Iterate twice through opendir(), readdir(), closedir() with one malloc().

  2. Iterate one through opendir(), readdir(), closedir() with multiple realloc().

For performance, I would use a 3rd option: linked list instead of using an array of struct dirent

  1. Iterate once through opendir(), readdir(), closedir() with one malloc() per entry.

As with such performance issue: strive for reduced big O, not linear ones.

\$\endgroup\$
1
  • \$\begingroup\$ I like how you understand my question. You put my problems in better words than I did :) \$\endgroup\$ – user220256 Jun 15 '20 at 23:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy