Hello. Could someone please help me understand what's going on with this code?

What I'm trying to do is read each line of a file into a vector<char const *>. I feel like the answer is probably extremely obvious but I just can't figure it out.

int main( int argc, char ** argv )
{
  int i = 0;
  std::vector<char const *> vec;
  std::ifstream file("abcd.txt");

  if ( file.is_open() ) {
    std::string temp;
    while ( std::getline(file, temp).good() ) {

      std::cout << "temp.c_str() " << i << ": " << temp.c_str() << "\n\n";

      vec.push_back(temp.c_str());

      for (int j = 0; j < vec.size(); ++j) {
        std::cout << "    vec.at(" << j << ") : " << vec.at(j) << "\n";
      }
      std::cout << "\n";

      ++i;
    }
  }
}

This is the text file.

aaaaaa
bbbbbbbbbbbb
ccccccc
ddddddddd

This is the output:

temp.c_str() 0: aaaaaa

vec.at(0) : aaaaaa

temp.c_str() 1: bbbbbbbbbbbb

vec.at(0) : XT
vec.at(1) : bbbbbbbbbbbb

temp.c_str() 2: ccccccc

vec.at(0) : XT
vec.at(1) : ccccccc
vec.at(2) : ccccccc

temp.c_str() 3: ddddddddd

vec.at(0) : XT
vec.at(1) : ddddddddd
vec.at(2) : ddddddddd
vec.at(3) : ddddddddd

You're pushing char pointers into the vector that become invalid when temp is changed.
You need to make a vector of strings or you need allocate memory for each char array and copy the string into it.

Comments
Quick reply telling me exactly what I needed

You're pushing char pointers into the vector that become invalid when temp is changed.
You need to make a vector of strings or you need allocate memory for each char array and copy the string into it.

Awesome, thank you so much. Been wrestling with this all day...if only the solution to all my problems was so easy.

Fixed code for anyone who is as silly as I am.

int main( int argc, char ** argv )
{
  std::vector<char const *> vec;
  std::ifstream file("abcd.txt");

  if ( file.is_open() ) {
    std::string temp;
    while ( std::getline(file, temp).good() ) {
      
      char * allocatechar = new char[temp.size() + 1];
      copy(temp.begin(), temp.end(), allocatechar);
      allocatechar[temp.size()] = '\0';
      
      vec.push_back(allocatechar);
    }
  }
}

Edited 6 Years Ago by Sarkahn: n/a

Why are you even using char* instead of the standard string type anyway?

I wish I could use strings, but I'm trying to learn OpenGL. One of the primary functions glShaderSource requires shader source code in the form of an array of null terminated strings, AKA char const **.

I don't know any C and I'm comfortable working with vectors so I figured I'd try it. My idea failed though. glShaderSource is parsing my vector in weird ways so I'll have to try a different approach I guess.

This question has already been answered. Start a new discussion instead.