0

So, basically I'm having an assignment, but that isn't the actual problem. The assignment requires me to use a list, which is fine so far.

So the idea is the following: I'm having a function which prints the contents of a directory recursively, which works fine, but now I'm trying to get each entry saved in a queue, which I'm later gonna use for something else. The nasty part is that I push each entry (the d_name from the dirent structure) into the queue in that function, and if I print the contents of the queue directly at the end of the function, it returns fine, but if I print the results in main, I get also garbage.

So my test directories look like this:

-DummyDir
    -DummyDir2
         -DummyDir6
         -DummyDir7
    -DummyDir3
         -DummyDir8
    -DummyDir4
         -DummyDir9
         -DummyDir10
    -DummyDir5
         -DummyDir11
         -DummyDir12

My function looks like this:

void dirwrap(char* dir, std::queue<char*>* queue)
{
   DIR* dirOpen;

   if(!(dirOpen = opendir(dir))){
     printf("Couldn't open directory: %s\n", dir);
     exit(-1);
   }

   struct dirent* dd;
   char path[2000];

   while ((dd = readdir(dirOpen)) != NULL)
   {
      if (strcmp(dd->d_name, ".") != 0 && strcmp(dd->d_name, "..") != 0) {

        //printf("%s\n", dd->d_name);
        queue->push(dd->d_name);        

        sprintf(path, dir, "%s", sizeof(dir));
        strcat(path, "/");
        strcat(path, dd->d_name);
        dirwrap(path, queue);
      }
  }
  closedir(dirOpen);
}

And if I print the contents of queue right after closedir I get a good result, like this:

DummyDir2
DummyDir6
DummyDir7
DummyDir5
DummyDir12
DummyDir11
DummyDir3 
DummyDir8
DummyDir4
DummyDir9
DummyDir10

But if I print the contents of my queue in main, I get this:

DummyDir2
DummyDir9
DummyDir10
DummyDir5
8�)�W▒
.
DummyDir3
~n��w▒
DummyDir4
DummyDir9
DummyDir10

I really can't seem to understand why is actually doing this, so I would really appreciate it if you would help me.

3
  • Any reason you aren't using std::string's? Commented Mar 20, 2019 at 21:17
  • Not really, I just used std::queue as a test in C++, since I have to do the assignment in pure C, and I wanted to test if was having the same problem with std::queue, so I didn't really change to std::string. Commented Mar 20, 2019 at 21:22
  • @CatalinC you need to duplicate dd->d_name whatever the way, see my answer Commented Mar 20, 2019 at 21:25

1 Answer 1

2

In

while ((dd = readdir(dirOpen)) != NULL)
{
   if (strcmp(dd->d_name, ".") != 0 && strcmp(dd->d_name, "..") != 0) {

     //printf("%s\n", dd->d_name);
     queue->push(dd->d_name);        

dd->d_name is an array inside the returned value, typically :

     struct dirent {
          ino_t          d_ino;       /* Inode number */
          off_t          d_off;       /* Not an offset; see below */
          unsigned short d_reclen;    /* Length of this record */
          unsigned char  d_type;      /* Type of file; not supported
                                         by all filesystem types */
          char           d_name[256]; /* Null-terminated filename */
      };

you need to duplicate it (e.g. strdup or use a std::string etc) because the data returned by readdir() may be overwritten by subsequent calls to readdir() for the same directory stream, and it will be freed by closedir

You are in C++ replace std::queue<char*>* queue by std::queue<std::string>* queue (or std::queue<std::string> & queue) or replace queue->push(dd->d_name); by queue->push(strdup(dd->d_name));

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, using strdup worked. Oh, sorry about using char* there, I was just using std::queue to test if it was also causing me the same trouble as in C (using a queue implemented by me). If I was doing this in C++, I would have used std::string from the get go :)
Don't worry, I did.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.