简体   繁体   中英

C++ Vector pointer problems/Vector of pointers to a object in a vector

So, it seems that a lot of people new to C++ have problems with vectors, as their is a ton of questions about vector. I am not really new to C++ but I have never had this problem. Anyway, so my problem is with vector pointers. I am making a video game with a vector that holds the objects. It holds a reference to the objects so it can do collision response inside the collision function. To load the vector I used to do something like this:

Object a = Object(12, 135, 123, 124);
collision_rects.push_back(&a);

It worked perfectly like this, however I didn't want to type each individual object, so I made a function that read it from a text file, like this.

void get_from_file()
{ 
//Blah blah read numbers from file.
//then I would get the numbers and make a object from them.
Object a = Object(numbers from file);
collision_rects.push_back(&a);
}

But doing this didn't work! I fall through the floor! If I take the same data and load it the first way it works fine, but when I do it from a function in a text file it doesn't. I then realized that maybe it was because the Object went out of scope. So I tried making an object global then doing the same in the function, which worked. This is essentially the same as the first option but in a function. So I made two vectors, on the same scope so that the original object would not go out of scope like this.

std::vector<Object> objects;
void get_from_file()
{
//blah blah
objects[i] = Object(nums from file); //reading from numbers in a for loop
collision_rects.push_back(&objects[i]); //This throws weird

This didn't work either.(By the way, this is not even close to actual code, just a example of what the code does basically. What am I doing wrong? Thanks. EDIT So I don't know if I explained it perfectly, but I don't think its the problem that its pointing to a deleted object. That certainly would make it not work, however it is also another reason I believe.

player->cHandler.objects.push_back(&uno); player->cHandler.objects.push_back(&dos); player->cHandler.objects.push_back(&tres); player->cHandler.objects.push_back(&quatro); player->cHandler.objects.push_back(&cinco); player->cHandler.objects.push_back(&seis); player->cHandler.objects.push_back(&a8); player->cHandler.objects.push_back(&a9); player->cHandler.objects.push_back(&a10); player->cHandler.objects.push_back(&a11); player->cHandler.objects.push_back(&a12); player->cHandler.objects.push_back(&a13); player->cHandler.objects.push_back(&a14); player->cHandler.objects.push_back(&a15); player->cHandler.objects.push_back(&a16); player->cHandler.objects.push_back(&a17); player->cHandler.objects.push_back(&a18); player->cHandler.objects.push_back(&a19); player->cHandler.objects.push_back(&a20); Now this is my actual code that works. However when I do it like this, it doesn't work.

objs.push_back(uno); objs.push_back(dos); objs.push_back(tres); objs.push_back(quatro); objs.push_back(cinco); objs.push_back(seis); objs.push_back(a8); objs.push_back(a9); objs.push_back(a10); objs.push_back(a11); objs.push_back(a12); objs.push_back(a13); objs.push_back(a14); objs.push_back(a15); objs.push_back(a16); objs.push_back(a17); objs.push_back(a18); objs.push_back(a19); objs.push_back(a20); for (int i = 0; i < objs.size(); i++) { //player->cHandler.objects.push_back(&objs[i]); } objs.push_back(uno); objs.push_back(dos); objs.push_back(tres); objs.push_back(quatro); objs.push_back(cinco); objs.push_back(seis); objs.push_back(a8); objs.push_back(a9); objs.push_back(a10); objs.push_back(a11); objs.push_back(a12); objs.push_back(a13); objs.push_back(a14); objs.push_back(a15); objs.push_back(a16); objs.push_back(a17); objs.push_back(a18); objs.push_back(a19); objs.push_back(a20); for (int i = 0; i < objs.size(); i++) { //player->cHandler.objects.push_back(&objs[i]); } This is not working, and I don't know why.

Your issue has nothing to do with std::vector . You only discovered the underlying problem by using vector , however you would have the very same problem if you returned a pointer to the object you created, or if you had a plain array and stored a pointer to the object in the array.

You're storing pointers to a local variable:

void get_from_file()
{ 
    Object a = Object(numbers from file);
    collision_rects.push_back(&a);
}

When the get_from_file() function returns, that a will be destroyed since it is a local object. Your collision_rects vector will thus have a pointer to a variable that no longer exists.

The same issue would have occurred with this code:

Object* get_from_file()
{ 
    Object a = Object(numbers from file);
    return &a;  // returning pointer to local variable.  Bad.
}

So the solution is to make sure that the object's lifetime exists outside the get_from_file function.

You can either store objects in your vector (a std::vector<Object> ), or if it must be pointer, it should be a pointer to an object that has a lifetime beyond the get_from_file() function. That can be accomplished by allocating from the heap using new , or better yet, using a smart pointer type.

You're storing a pointer to the objects, but the objects are then being destroyed so you're left with a pointer to nothing.

One good option is to store the objects themselves in the vector rather than the pointers.

Alternatively you could allocate an object on the heap (using eg new Object(1, 2, 3) ) and store that pointer (that way the object isn't destroyed until you want it to be). If you do that I would recommend storing a shared_ptr or unique_ptr - they do a lot of the work for you and make it easier to write correct code.

If it's ok for you that objects in your std::vector get destroyed when std::vector is destoyed, store them in std::vector<Object> , and use emplace_back to construct them directly in the vector, without the need of temporary local variable:

std::vector<Object> collision_rects;
collision_rects.emplace_back(nums from file);

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