0

Essentially, what I'm trying to do is to check the last access time of a file and compare it with a string. Here's the relevant block:

struct stat file;
char timeStr[ 100 ];

stat(nodes.at(0), &file);
strftime(timeStr, 100, "%H:%M:%S-%m/%d/%y", localtime(&file.st_atime)); /* problem */

nodes is a vector of file paths; I'm not sure if it's relevant but I'll include the code that I'm using to set nodes:

vector<char*> nodes;
DIR *dir;
struct dirent *cur

if((dir = opendir(searchPath.c_str())) == NULL) {
    cout << "Error opening search path. Are you sure '" 
        << searchPath.c_str() << "' is a valid search path?" << endl;
    return 0;
}
while((cur = readdir(dir)) != NULL) {
    if(string(cur->d_name) == "." || string(cur->d_name) == "..") continue;
    nodes.push_back(cur->d_name);
}
closedir(dir);

Where searchPath is a user-inputted string.

The problem: when the 'problem' line is run, from there on nodes is a vector of garbage. I'm wondering if I can accomplish this task without turning nodes into garbage.

Since this is homework, and as you can probably tell I'm not used to C++, a solid push in the right direction will be given the 'accept'.

Thank you.

wanovak
  • 6,117
  • 25
  • 32
  • What's relevant is the code calling the `localtime()` stuff. It is also a bad idea to gang function up on each other like you're doing; you skip the error checking. You should check that `stat()` succeeded, for example, before using the data from the structure. – Jonathan Leffler Jan 18 '12 at 01:17
  • Your `nodes` is a vector of `char *`, not a vector of `string`. Have you printed out your nodes list at the end of the read code, between the while loop and the closedir()? I'd not be surprised to find they all point to the same name. (If you leave it later to do the printing, the space may have all been screwed up.) – Jonathan Leffler Jan 18 '12 at 01:18
  • `nodes` only gives me funky results after running `localtime`; in all other cases I can loop through `nodes` after the setting code and see the file names just fine (with `cout`.) – wanovak Jan 18 '12 at 01:23

2 Answers2

1
nodes.push_back(cur->d_name);

You're storing pointers in the vector that immediately become invalid (cur is valid until the next readdir or closedir call). The best fix is to code what you want -- make nodes a vector of strings. The easiest fix:

nodes.push_back(strdup(cur->d_name));
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

It has nothing to do with your strftime call but with the fact that (from here):

The pointer returned by readdir() points to data which may be overwritten by another call to readdir() on the same directory stream.

Since you're simply pushing a character pointer that points to data that may be overwritten by subsequent calls to readdir, you may well end up with garbage.

You can probably fix it by using a copy of the C string with something like:

nodes.push_back (strdup (cur->d_name)); // plus error handling if need be.

And, if your implementation doesn't have a strdup (it's not part of the standard), you can use mine (found here).

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Thank you; I suspected that something may have been wrong at that point in the program. However, when using your implementation I'm getting the following error (first line of the function): `invalid conversion from void* to char*`. I'm assuming that's a problem on my end and that your code is fine. – wanovak Jan 18 '12 at 01:32