-4
struct Word {

    string wordName; //loses its value
    vector<string> contents; //irrelevant for the question
    int numContents = 0; //maintains its value

};

vector<Word*> wordMsgs;

int main()
{

vector<string> result;
result.push_back("wordName");
result.push_back("shouldEnterIf");

Word curr;
        //New Word
        if (result[1] != "") {
            Word w;
            w.numContents = 10; //just a testing #, suppose to represent size of vector
            wordMsgs.push_back(&w);


            w.wordName = result[0]; //name of Word


            //here w.wordName and (*wordMsgs[0]).wordName display the same string; result[0] 
            curr = w;
        }
        //here curr.wordName displays result[0] but (*wordMsgs[0]).wordName doesn't. However, (*wordMsgs[0]).numContents returns 10 as expected
}
}

So I have a vector of struct references, assuming the push_back() method for vectors only pushes a copy to the end of the vector. I create an instance of my Word struct and put that reference into my vector, wordMsgs. I then edit the struct it is pointing too and then my string variable is lost upon leaving the if statement! However, my int variable never loses its value. I don't understand because I used pointers (and I'm in C++ so I thought strings were a-okay) and I wouldn't think this is a local variable issue...

3 Answers3

1

The variable w in:

    if (...) {
        Word w;
        wordMsgs.push_back(&w);
        ...
    }

Is allocated on the stack inside the scope of the if statement.

You are then adding its address to your vector of pointers.

Once outside the if statement, this variable is deallocated and the value at that address is no longer "solid", so you essentially have a "garbage address" in that vector.

From here onward, the behavior of your program is mostly unpredictable...

goodvibration
  • 5,302
  • 1
  • 17
  • 43
  • _"From here onward, the behavior of your program is mostly unpredictable..."_ Well, that's called _undefined behavior_. Thus we already have a standard definition of that situation. – πάντα ῥεῖ Jun 13 '19 at 19:19
  • Recommend adding a solution like changing `vector wordMsgs;` to `vector wordMsgs;` and discarding the pointer completely – user4581301 Jun 13 '19 at 19:22
0

Here is a minimal example of what is going wrong in your code:

#include <string>
#include <vector>
#include <iostream>

int main() {
   std::vector<string*> words;     // why pointers?

   if (true) {                    // scope starts here
       std::string word = "muh";   
       words.push_back(&word);    // dont do that !!
   }                              // scope ends here

   std::cout << *words.back(); 
}

By the time you access the string by dereferencing the pointer, the string is long gone, because word is destroyed when it goes outof scope. Dereferencing the pointer is undefined behaviour. You shouldnt have raw pointers in the vector when you dont need to. You probably wanted something like this:

#include <string>
#include <vector>
#include <iostream>

int main() {
   std::vector<string> words;

   if (true) {               
       std::string word = "muh";   
       words.push_back(word);      // vector stores a copy ! and manages lifetime of its elements
   }                         

   std::cout << words.back(); 
}
463035818_is_not_a_number
  • 64,173
  • 8
  • 58
  • 126
0

You have a vector of pointers, not refrences. When you push back the adress of the locally defined struct Wors w by using &w you will lose that data directly when you go out of the if statement. You need to allocate and deallocate memory for the vector. Best to either just push objects in the vector or use a smart pointer.

Bart
  • 842
  • 3
  • 23