wanovak
wanovak

Reputation: 6127

localtime alternative that won't overwrite the supplied struct

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.

Upvotes: 0

Views: 279

Answers (2)

paxdiablo
paxdiablo

Reputation: 882028

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).

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182819

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));

Upvotes: 1

Related Questions