简体   繁体   中英

Pointer confusion - c++

I've been tasked with making a simple change to a C++ application. Unfortunately I come from a Java background, and I've hit a wall with some pointer problems.

The code in question reads in a list of files from a given directory (set using an environment variable), and does something on each file.

char * rebuildDir = getenv("REBUILD_DIR");
char * currentFile;
DIR *asciiDir;
struct dirent *ent;

asciiDir = opendir(rebuildDir);
if (asciiDir != NULL)
{
    while ((ent = readdir(asciiDir)) != NULL)
    {
        std::cout << "rebuild sensor, rebuild dir is " << getenv("REBUILD_DIR") << std::endl;
        currentFile = rebuildDir;
        strcat(currentFile, ent->d_name);
        ifstream raw(currentFile);
        while(raw)
        {
            ...snip...
        }
        raw.close();
    }

    closedir(asciiDir);
}

As you can see, the intention is to store the environment variable once, then copy it to currentFile, then concatonate the current filename to currentFile, ready to pass into ifstream.

The problem is that

currentFile = rebuildDir;

does not reset to the environment variable, so strcat keeps on using the old filename and appending to it, so:

/home/file1
/home/file2
/home/file3

will execute as

/home/file1
/home/file1/home/file2
/home/file1/home/file2/home/file3

through the loop. I'm guessing I'm making an elementry mistake with my pointers, but I haven't been able to track it down.

Thanks for any help, and apologies for the trivial question.

PS - if there's a obviously better approach to accomplish my task, please feel free to point it out:)

Current file points to the same memory as rebuilddir so you modify the string in place. You need to duplicate the string. You could do something like:

char currentFile[MAX_PATH];
snprintf(currentFile, MAX_PATH, "%s%s", rebuildDir, ent->d.name);

"... does not reset to the environment variable". Why would it "reset" to anything? You are aiming your pointer currentFile to the actual environment variable value pointed by rebuildDir . And then you are modifying the pointee by strcat , ie you are essentially modifying (ie destroying) your original environment variable value.

You shouldn't do that. If you want to build the new name from the value of the environment variable, you have to copy that value aside and then modify the copy, instead of trying to destroy the original.

For example, you can use std::string to create the copy on the original value

const char *rebuildDir = getenv("REBUILD_DIR");
...
std::string currentFile = rebuildDir;
currentFile += ent->d_name;
ifstream raw(currentFile.c_str());
int main(int argc, char *argv[])
{
    char* pDir = getenv("REBUILD_DIR");

    if (! pDir)
    {
        cerr << "did not find ENV var\n";
        exit(1);
    }

    string rebuildDir(pDir);

    DIR* asciiDir;

    if ((asciiDir = opendir(rebuildDir.c_str())) != NULL)
    {
        std::cout << "rebuild sensor, rebuild dir is " << rebuildDir << std::endl;

        struct dirent *ent;

        while ((ent = readdir(asciiDir)) != NULL)
        {
            string currentFile(rebuildDir);

            currentFile += '/' + string(ent->d_name);

            //probably want to skip "." and ".." entries...

            /*
            ifstream raw(currentFile);

            while(raw)
            {
                ...snip...
            }

            raw.close();
            */
        }

        closedir(asciiDir);
    }
    else
    {
        cerr << "coult not open dir\n";
        exit(1);
    }

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM