Tyler Harwood
Tyler Harwood

Reputation: 5

C++ Static vector loses data after exiting function

I have a static function:

void TextManager::printDialogue(vector<Button*>* options, int optionsCount, vector<string> outputDisplayText)
{
    active = true;
    buttons = *options;
    buttonsCount = optionsCount;
    outputText = outputDisplayText;
}

The "buttons" variable is static:

static vector<Button*>  buttons;

I make a call to printDialogue in an execute function:

void WorldDoor::execute()
{
    vector<Button*> buttons;

    buttons.push_back(new CancelButton());
    buttons.push_back(new ChangeRoomButton(room));

    TextManager::printDialogue(&buttons, 2, messages); //<----

    std::vector<Button*>::iterator i = buttons.begin();

    for ( i = buttons.begin() ; i < buttons.end(); i++ )
    {
        delete * i;
    }
}

For whatever reason, when I debug and have a break point inside of the printDialogue function, the values in "buttons" are perfectly fine. However, after I leave printDialogue, the strings contained in my buttons go from being readable to giving me an error message saying:

I tried passing a pointer to an array instead of using

vector<Button*>

but it was only reading the first variable. Now it is not reading anything. Could anyone please help?

Upvotes: 0

Views: 1507

Answers (2)

Jamin Grey
Jamin Grey

Reputation: 10495

Edit: Completely misunderstood the question.

When you do this:

vector<int*> vector1;
vector<int*> vector2;

vector1.push_back(new int(5));

vector2 = vector1;

It copies the pointers, not the value of the pointers. So when you later iterate over the first vector and delete the dynamic memory, both vectors have pointers pointing to the same memory that you deleted, so your second vector is pointing to invalid memory.

If you are using C++11, you can use a vector of unique pointers, and std::move() one vector into another. Otherwise, you can just call 'clear()' on the vector, without deleting the memory.

Here's how the function could be written:

void TextManager::printDialogue(vector<Button*>* options, int optionsCount, vector<string> outputDisplayText)
{
    active = true;
    buttons = *options;
    options->clear(); //<--- Instead of crawling over it and delete-ing it.
    buttonsCount = optionsCount;
    outputText = outputDisplayText;
}

Everything below this was my misunderstanding the question: (contains other information that might be important)

When you do:

vector<Button*> buttons;

Inside the function, you are creating a new vector called 'buttons', which gets destroyed at the end of the function call.

If you want to access the global one, don't create a new one inside the function, or name them something different.

Example:

int myVar = 100; //Declares a variable called 'myVar' at global scope.

void func()
{
    int myVar = 200; //Declares a *different* variable called 'myVar' at function scope.
    std::cout << myVar << std::endl; //Prints the one inside the function, not the one outside it.
}

By the way, the variable 'static' shouldn't be used at global scope, unless the variable belongs to a class. To make a variable global, you just put it outside of any function. To make a class member shared between all instances of that class, you declare it static so that class knows to have all instances share the one variable. It's a different thing. =)

If you have your code split into multiple files, to make a global really-truly global, you have to declare it 'extern' in your header, and not extern in one source file, and have other source files #include the header that externs it. Slightly clunky, but that's how it's done. They are working on a better system for it, but it'll be several years before it becomes standardized.

Upvotes: 0

ruben2020
ruben2020

Reputation: 1549

There is a static member variable called buttons, and also a local variable inside execute() called buttons. You should rename to avoid confusion, otherwise, the local variable will be used instead of the static member variable inside execute().

Upvotes: 1

Related Questions