Weird issue with stl vector in VC++ .NET 2003

Started by
3 comments, last by meh 18 years, 4 months ago
Hello, I'm working on a project where im maintaining a list of directory names by saving them inside of a vector for use later. The vector is declared locally within the function. The problem I'm having is that everytime i push a new name into the vector its not maintaing any of the other things i know should have been stored. Here is a snippet of the code (this code is part of a while loop that i have omitted):

vector<char*> directories;    // a list of subdirectories for a given directory

if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
  char temp[256];
  strcpy(temp, FindFileData.cFileName);
  directories.push_back((char*)temp);   // store the name of the file in the vector
}

 for(vector<char*>::iterator iter = directories.begin(); iter != directories.end(); iter++)
 {
    cout << *iter << endl;   // THIS line only prints the last element in the vector
 }
www.lefthandinteractive.net
Advertisement
If you're already using std::vector, you should use std::string as well. Include <string>, and instead of a char*, use a std::string. The problem you're having is a classic one, where you're simply remembering a pointer to a bunch of characters, not the characters themselves. Your characters, appropriately named "temp", are getting lost, but your pointer to those characters remains.

std::string, however, actually remembers the characters themselves, copies all characters when necessary, and other such basic string utilities. Here's your code, rewritten with std::string:


vector<string> directories; // a list of subdirectories for a given directory

if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
directories.push_back(FindFileData.cFileName); // store the name of the file in the vector
//note that the char* cFileName member will automatically get turned into a std::string.
//the std::string constructor will copy all the characters from the char* buffer
//into its own internal buffer, so no matter what happens to the original string
//of characters, the new std::string will remember the data
}

for(vector<string>::iterator iter = directories.begin(); iter != directories.end(); iter++)
{
cout << *iter << endl; // THIS line only prints the last element in the vector
}
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){  // This is where your problem is. temp will be destroyed when exiting the  // scope. So the string pointed to in the array is no longer valid.  char temp[256];  strcpy(temp, FindFileData.cFileName);  // You are not storing a copy of temp here but a pointer to your  // temporary array that gets destroyed.  directories.push_back((char*)temp);   // store the name of the file in the vector}


Try to use:
vector<std::string> directories;

instead of:
vector<char*> directories;

perhaps?
-Benny-
Thanks, changing the "char*" to "std::string" did the trick. Thank you for the help.
www.lefthandinteractive.net
The temp variable is going out of scope outside of the if statement, therefore the pointer is no longer valid. In this instance it makes sense to allocate memory for the string (strlen + 1) and then strcpy. You do need to remember to deallocate the memory as you remove items from the vector.

As mentioned storing using string would alleviate the problem as well.

char * temp = NULL;...if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){  temp = new char[strlen(FindFileData.cFileName) + 1];  strcpy(temp, FindFileData.cFileName);  directories.push_back((char*)temp);   // store the name of the file in the vector}  


Edit: noticed someone said this before in the code example. :)

This topic is closed to new replies.

Advertisement