Stack objects being inserted into containers? - c++

In C++ what happens if you create an object on the stack (within a function) and insert it into a heap-allocated container (which has been passed into the function/exists after the function finishes)?
The stack object has local scope, but the container it has been inserted within, is on the heap and can last after the function (where the insert was made) has returned. Is the stack object still retrievable from the container after the function returns?
void Test( std::vector<MyClass>& myvec )
{
MyClass m;
myvec.push_back(m);
}

In this particular case, m will be copy-constructed into a new instance of MyClass, which will be owned by the vector. So a different but equivalent instance of MyClass can be retrieved from the vector, yes.

Base assumption: when you use Vector, you really mean std::vector. The answer could change with a container that's designed enough differently.
As long as you do like you usually should, and store objects (not pointers) in the container, you're all right, because what's stored in the container is normally a copy of the object you pass.
Under the right circumstances, the object in the container can be move constructed from what you pass, but the effect is basically the same -- you end up with an object whose lifetime continues until it's removed from the container (or the container is destroyed, etc.)

Is the stack object still retrievable from the container after the function returns?
Yes, your myvec.push_back(m); makes a copy of m and a new copy is manged by vector.
However, after your function returns myvec doesn't have m inside because you pass myvec into Test function by value, Test function makes a temporary copy of myvec and copy m into it, after function returns the temporary copy of myvec is released. So you meant to pass myvec to Test function by reference as below:
public void Test(Vector<MyClass>& myvec){
MyClass m;
myvec.push_back(m);
}

As noted by other answers, m is copied into vector. That said, your function receives vector by value too (UPD: it was true for the original code, which was edited since), and it's obviously not what you wanted.

The code in the question will create a copy of MyClass in the std::vector. The original m will be destructed when the Test method exits.
If we change the vector to store pointers to MyClass we have two possible options.
void Test( std::vector<MyClass*>& myvec )
{
// Allocates a new MyClass on the heap.
MyClass* pM = new MyClass();
myvec.push_back(pM);
// This variable will be allocated on the stack and cleaned up on method exit
MyClass dontDoThis;
myvec.push_back(&dontDoThis);
}
At the end of this method myvec has two elements, myvec[0] and myvec[1].
When a container of pointers is stored then the object must be allocated so that it is valid for the length of time the pointer is in the container. In the example above the pM pointer will be valid after the Test method exits. This means that myvec[0] will be a valid pointer after the method exits.
Initially, a valid pointer to dontDoThis variable will be added to the vector, but when the method exits the destructor of dontDoThis will be called and the memory will probably be used to store other data. The pointer in myvec looks ok, but any attempt to actually use it will cause undefined behaviour. On method exit the pointer in myvec[1] might look valid, but actually it points to junk.
Note that at a later time, when myvec[0] is changed or deleted, it is important to call:
delete myvec[0]
to ensure that the object is cleaned up properly. Otherwise a memory leak will occur.
After explaining what will happen with naked pointers, I strongly recommend you use smart pointers such as std::unique_ptr and std::shared_ptr

Is the stack object still retrievable from the container after the function returns?
Only if MyClass has a "gut" copy constructor. (Deep copy or sharing ownedship of other resuorses, etc)
I mean, it could be retrived but it could be in a broked state

Related

Is it possible to return an a reference to the data in an std::vector, and preserve that reference after the vector goes out of scope?

I am used to programming in C, and in that language I would just return a pointer to the data, and then the caller would be responsible for freeing the data, however, from what I've read, the vector's destructor will be called as soon as it goes out of scope, causing it's data to be de-allocated.
Once the reference is returned, the size of the contents will not change, so if I could just have a pointer to the data that I could manually delete afterwards that would be ideal. What I really do not want to do is copy all of the data into a new container, since this vector is going to grow to be very large.
Any help would be appreciated. Every solution I have seen so far involves either copying by value and relying on the compiler to optimize it, or using additional classes to wrap the vector.
Edit: To be clear, the only part of the vector which I want to keep is a pointer to its data (I.E. the pointer you get using the vector.data() method), I don't need to keep any other information about the original vector.
Good (safe and fast) solution for the use case that you describe: Don't return a reference, return the vector to the outside of the scope instead.
Is it possible to return an a reference to the data in an std::vector, and preserve that reference after the vector goes out of scope?
Yes... if you use static storage. The lifetime of objects with static storage duration extends until the end of the program. Therefore they stay alive when they go out of scope. Note that static storage is global state, which is often problematic. Avoid if you can and use with care.
With automatic storage: No.
I would just return a pointer to the data, and then the caller would be responsible for freeing the data
This is a problematic approach. How does the caller know that they are responsible for freeing the data? How does the caller know how to free the data? How does the caller know when they can free the data (in case there are other users of the data)? This all relies on the caller to read the documentation, understand it, and not make a mistake. This is a source of many memory leaks, accesses through invalid pointers and double free crashes.
std::vector solves those problems (to some degree; there are no interfaces in C or C++ that cannot be misused if one tries hard enough) by keeping the lifetime tied to the container object.
If I could just have a pointer to the data that I could manually delete afterwards that would be ideal.
You cannot have that. std::vector always destroys its data, and it is not possible to steal the data to the outside of the vector (except into another vector through move or swap).
The whole point of a reference is that it doesn't own the object. It's perfectly valid to use a std::unique_ptr here, which owns the object and can be returned to your caller.
Your function would be defined as follows (I assume a vector of integers), and C++14 or newer:
std::unique_ptr<std::vector<int>> getVector() {
auto vec = std::make_unique<std::vector<int>>(/*any ctor args you want*/);
// for example
vec->push_back(1);
vec->push_back(2);
return vec;
}
A caller can then do as follows:
int main() {
auto vec = getVector();
std::cout << vec->size() << std::endl;
}
and the vector will be safely deleted as the unique_ptr goes out of scope. Note that if you are using C++11, you won't have std::make_unique and will need to do something like:
std::unique_ptr<std::vector<int>> vec(new std::vector<int>(/* ctor args */));
Just write your code like this:
std::vector<blah> my_function_that_returns_a_vector ()
{
std::vector <blah> v;
... code to populate v ...
return v;
}
NVRO will then eliminate the copy. Instead, the vector returned is constructed directly in the caller's stack frame.
It is not possible to preserve the reference to a vector after it goes out of scope because, and you mentioned, it will be deleted. Once the vector is deleted, the memory stored at that address will be inaccessible. Alternatively, you can declare the variable outside of the scope, edit it within the scope. You mention returning by reference - is it possible that you can pass the vector into the function by reference, and simply return void? This way, you can edit the same vector in different scopes.

Can I keep vector data even after out of scope

I come from a C background. I used to allocate memory/array, for example, sending it to somewhere else, and the pointer stayed there, even after, the scope where it was allocated was destroyed.
Now, if I do the same with vectors : initialize, pass it by reference, and then keep that reference saved somewhere. After the initial method, that actually created the vector, goes out of scope, would it be destroyed ? Or as the pointer to it is still saved, it will be kept.
std::vector frees the memory it holds when it is destroyed. Holding a reference to an object that gets destroyed is very bad. Accessing it is UB. General rule: Do not store references, only use them where you can be sure that the object exists for the entire scope, e.g. as parameter of a function.
If you want to keep a copy of the data, simply copy the std::vector. No reference needed.
If you want to be able to access the data from different locations, and have it live as long as at least one location still has a reference/pointer to it, don't use std::vector, use std::shared_ptr.
If you want to combine the benefits of std::vector with the benefits of shared memory that lives until the last place lets go of it, combine them: std::shared_ptr<std::vector<...>>.
If you want to have the std::vector live in one place for a bit, and then live in another place but not in the first place anymore, use move semantics:
std::vector<int> foo = {1, 2, 3};
std::vector<int> bar = std::move(foo); // bar now holds the data that foo held, foo is empty, no copy was performed
A pointer to an array on the stack will not keep the array alive, I suppose thats the same in C. Now a vector is not an array. It is a wrapper around a heap allocated array which frees the memory of the array when it goes out of scope.
... because a pointer to it is still saved it will still be kept?
No! A pointer or reference to a std::vector will not keep the vector alive. The canonical wrong example is:
std::vector<T>& foo() {
std::vector<T> x;
return x;
} // baaam !
The reference returned from the function is dangling. YOu cannot do anything with it. The correct way would be to return by value and rely on return value optimization:
std::vector<T> foo() {
std::vector<T> x;
return x;
}
If you do:
auto y = foo();
No copying is involved, thanks to NRVO.
PS: Compilers should warn you about returning a reference to a local variable.
No if I do the same with vectors, I initialize a vector, pass it by reference, then keep the reference saved somewhere. After the initial method that actually created the vector goes out of scope, would it be destoryed?
Yes.
or because a pointer to it is still saved it will still be kept?
No.
You can have dangling pointers in C++ just like you can in C. It's exactly the same.
This is also often the case for references (though in some cases the lifetime of the object is extended for a little bit).
It is true that the vector's data is internally managed by the vector, but that's by-the-by since you're asking about the vector itself. Forget the vector and ask the same question about an int, then you'll realise the answer is just as you'd expect it to be in C.
The existing answers are good, will add here:
block A
{
vector<int> my_vec(10, 0);
//...something...
}
block B
The my_vec vector will go out of scope and be destroyed at the closing bracket. Now that's stl (Standard Template Library) vectors.
You can also use C-style arrays (but with different syntax). For very large arrays, I have found the allocation time with a dynamically-allocated array to be faster than STL vectors.
//static, goes out of scope and memory handled at the end of code block
int arr0[10];
//dynamic, not destroyed unless delete called.
int* arr1 = new int[10];
//...work with arr1...
delete [] arr1;
Just like in C, you need to take care of de-allocating any memory you create using new.

Is an object pointer in a vector deleted if I call delete on the object?

Recently, I was confused on why I continuously was faced with a segmentation fault trying to access an element in a vector of pointers of certain objects. I didn't manage to resolve the issue, but I suspect that it is because after I pushed the object pointer into a vector, I called delete on it, thinking that the vector stored a copy.
In the following code:
std::vector<SomeObject *> testvector;
SomeObject * testobject = new SomeObject(/* some arguments here, call constructor */)
testvector.push_back(testobject);
delete testobject; // does this affect the element in the vector?
The debugger confirms that the pointers getting added to the vector do indeed have proper data, but once I call delete on them, I'm unsure if the element inside the vector is affected. Does the vector store just a copy? When I call delete on the object, I suspect that delete is being called on the pointer in the vector, but I am unsure.
Now I tried to print out the data in the vector after calling delete, I get this: ??? ?? ???? ???
And I am assuming that the call to delete has affected the vector element. Is this the case? I thought that after I added the pointer to the vector, I could safely free the object without affecting the element in the vector, but it seems that I end up accessing memory that is no longer allocated. Does the call to delete affect the pointer in the vector?
"Does the call to delete affect the pointer in the vector?"
It doesn't affect the pointer. It affects the behavior invoked by using this pointer since the object it points to no longer exists. When you call delete, the object is deleted and whatever you try to do with that object using invalid (old, dangling) pointer, the behavior is undefined.
std::vector<SomeObject *> testvector;
SomeObject * testobject = new SomeObject()
testvector.push_back(testobject);
Constructs a vector of pointers, creates an instace of SomeObject and pushes an address of this object to your vector. Then when you call:
delete testobject;
There is no way how std::vector could know that the object has been deleted. Your vector still contains an old pointer, which has became invalid by the time the object was deleted. A possible solution could be using a vector of smart pointers such as shared_ptr, however at first you should consider whether you want to use a vector of pointers at first place. Maybe std::vector<SomeObject> would be more reasonable way to go.
The vector contains pointers not the objects theirself. So after deleting an object the corresponding pointer will be invalid.
When you copy a pointer, you only copy the address of the object, not the object itself. That means the pointer in your vector and your pointer outside the vector were still referring to the same thing when you called delete.
The reason the debugger may still have shown seemingly valid data is because the memory doesn't necessarily get overwritten when you delete something. It's simply marked as 'free' so that it can be used by something else later if required.
Yes, both testobject and the inserted element into the vector are pointing to a same address. After deleting one of them another will be a dangling pointer and dereferencing it is undefined behavior.
You can use smart pointers such as std::unique_ptr or std::shared_ptr.
std::vector<std::shared_ptr<SomeObject>> testvector;
std::shared_ptr<SomeObject> testobject(new SomeObject);
testvector.push_back(testobject);
or
std::vector<std::unique_ptr<SomeObject>> testvector;
std::unique_ptr<int> testobject(new SomeObject);
testvector.push_back(std::move(testobject));
// After `std::move` you can not use `testobject` anymore!

Do containers (sets, vectors, etc) need to be created using the new keyword in order persist across functions?

I've been working on a school assignment that makes pretty heavy use of vectors, sets, stacks and queues.
What is the difference between Foo and Bar, especially when passing Foo and Bar between functions? When would it be safe to call delete on Bar, if ever? I'm guess it's never safe to call delete on Bar unless everything in that vector has been moved? If I return Foo, wont it (and its contents) be deleted when the function exits?
vector<Line *> Foo;
and:
vector<Line *> * Bar = new vector<Line *>();
Similary, lets say I have a function:
vector<Line *> BSTIndex::query(string expression)
{
vector<Line *> result; //Holds the lines that match the expression
string query = expression;
queue<string> * output = expressionParser(query);
doSomeStuffWithOutputHere();
return result;
}
And my expressionParser is:
queue<string> * BSTIndex::expressionParser(string query)
{
char * cQuery = new char[100];
strcpy_s(cQuery, 100,query.c_str());
//strcpy(cQuery, query.c_str());
queue<string> * output = new queue<string>(); //Operators go in the queue
stack<string> * s = new stack<string>(); //Operands go on the stack
performSomeMagicOnQueueAndStackHere();
return output;
}
The stack is actually only local to expressionParser so I KNOW I can remove the new keyword from that. The queue however, needs to go back to the query function where it's used but then that's it. Do I HAVE To create a pointer to the queue in this case (I want to say yes because it's going to fall out of scope when expressionParser returns). If I need to create the pointer, then I should call a delete output in my query function to properly get rid of the queue?
My last concern is the vector being returned by query. Should that be left as I have it or should it be a pointer and what's the difference between them? Once I consume that vector (display the information in it) I need it to be removed from memory, however, the pointers contained in the vector are still good and the items being pointed to by them should not be deleted. What's the best approach in this case?
What happens to the contents of containers when you call delete on the container? If the container held pointers, and those pointers are deleted won't that affect other areas of my program?
SO many questions (direct and indirect) crammed into such a small space!
What is the difference between Foo and Bar.
vector<Line*> Foo;
vector<Line*>* Bar = new vector<Line*>();
Foo is an object of automatic (potentially static (but the distinction is not important here)) storage duration. This means it is created at the point of declaration (constructors called) and destroyed when it goes out of scope (destructors called).
Bar on the other hand is a pointer. Pointer have no constructors or destructors and are used to point at other objects (or NULL). Here Bar is initialized to point at an object of dynamic storage duration. This is an object that has to be manually released (otherwise it will leak).
especially when passing Foo and Bar between functions?
When passing Foo (by value) to/from functions the copy constructor is used to make a copy of the original object. Note: The standard explicitly states that copying from a function (via return) can be elided (look up RVO/NRVO) and all modern compilers will remove the extra copy construction and build in place at the return site (but this is an optimization invisible to the user just think of it as a very efficient copy out of a function). The resut of this is that when passed into a function (by value) or returned from a function (by return) you are working on a new object (not the original). This is important because of the side effects of using the object will not affect the original. (see your question below about returning Foo).
When passing Bar (by value) the pointer is copied. But this means that what is pointed at is the same. So modifying an object via the pointer is modifying the original value. This makes passing it as a parameter very cheap (because all you are passing is the address of the object). But it makes returning a value potentially dangerous, this is because you could return the address of an object that has gone out of scope inside the function.
Using pointers in inherently dangerous and modern C++ programs rarely use RAW pointers directly. Pointers are usually wrapped up inside objects that manage the ownership and potentially lifespan of the object (see smart pointers and containers).
When would it be safe to call delete on Bar, if ever?
It is only safe to delete Bar if:
It is NULL
The object it points at has been dynamically allocated via new.
I'm guess it's never safe to call delete on Bar unless everything in that vector has been moved?
It would safe to delete Bar even if it's content had not been moved (though you could leak if the contained pointers were owned by Bar (this is not directly unsafe but can be inconvenient when you run out of space)). This is another reason pointers are rarely used directly, there are no ownership semantics associated with a pointer. This means we can not tell if Bar owns the pointers it holds (it is the responsibility of the owner to call delete on a pointer when it is no longer used).
If I return Foo, wont it (and its contents) be deleted when the function exits?
Yes. But because you return an object it will be copied out of the function. So what you use outside the function is a copy of Foo (Though optimizers may elide the copy because of RVO/NRVO. Not if the copy is elided the destructor is also elided).
Similary, lets say I have a function: query and expressionParser:
vector<Line *> BSTIndex::query(string expression)
{
vector<Line *> result; //Holds the lines that match the expression
string query = expression;
queue<string> * output = expressionParser(query);
doSomeStuffWithOutputHere();
return result;
}
queue<string> * BSTIndex::expressionParser(string query)
{
char* cQuery = new char[100];
strcpy_s(cQuery, 100,query.c_str());
queue<string> * output = new queue<string>(); //Operators go in the queue
stack<string> * s = new stack<string>(); //Operands go on the stack
performSomeMagicOnQueueAndStackHere();
return output;
}
The stack is actually only local to expressionParser so I KNOW I can remove the new keyword from that.
Not only can you but you should. As currently you are leaking this object when it goes out of scope.
The queue however, needs to go back to the query function where it's used but then that's it. Do I HAVE To create a pointer to the queue in this case (I want to say yes because it's going to fall out of scope when expressionParser returns).
No. You can pass the obejct back by value. It will be correctly copied out of the function. If you find that this is expensive (unlikely) then you could create a dynamic object with new and pass it back as a pointer (but you may want to look at smart pointers). Remember that pointers do not indicate that you are the owner so it is unclear who should delete a pointer (or even if it should be deleted). So (if passing a value is too expensive) use a std::auto_ptr<> and pass the pointer back inside it.
If I need to create the pointer, then I should call a delete output in my query function to properly get rid of the queue?
Yes. And No. If you create a dynamic object with new. Then somebody must call delete on it. It is bad C++ style to do this manually. Learn to use smart pointers so that it is done automatically and in an exception safe manor.
My last concern is the vector being returned by query. Should that be left as I have it or should it be a pointer and what's the difference between them?
I would do it like this:
vector<Line> BSTIndex::query(string const& expression)
{
vector<Line> result; // 1 Keep line objects not pointers.
queue<string> output = expressionParser(expression);
doSomeStuffWithOutputHere();
return result;
}
queue<string> BSTIndex::expressionParser(string const& query)
{
char cQuery[100]; // Don't dynamically allocate
// unless somebody takes ownership.
// It would probably be better to use string or vector
// depending on what you want to do.
strcpy_s(cQuery, 100, query.c_str()); // std::string can use the assignment operator.
queue<string> output; // Just build the que and use it.
stack<string> s; // Unless there is a need. Just use a local one.
performSomeMagicOnQueueAndStackHere();
return output;
}
Once I consume that vector (display the information in it) I need it to be removed from memory, however, the pointers contained in the vector are still good and the items being pointed to by them should not be deleted. What's the best approach in this case?
Depends who owns the pointers.
What happens to the contents of containers when you call delete on the container?
If the content of the containers are pointers. Then nothing. The pointers disappear (what they point at is unchanged and unaffected). If the container contains objects (not pointers) then the destructor is called on the objects.
If the container held pointers, and those pointers are deleted won't that affect other areas of my program?
It would. But you would have to call delete manually.
For the most part, what you normally want to do is just create an instance of the object in question, and when you need to return it, return it.
For something like a large container, that can (and often does) sound like it'd be horribly inefficient. In reality, however, it's usually quite efficient. The C++ standard has a couple of clauses to allow what are called Return Value Optimization (RVO) and Named Return Value Optimization (NRVO). Initially, what's in the standard doesn't sound very important -- it just says the compiler doesn't have to call the copy constructor for a returned value, even if the copy constructor has side effects so you can see that it's been omitted.
What this means in reality, however, is that the compiler (which is to say essentially all reasonably current compilers) will actually only create one collection at the highest level in the function call hierarchy where it gets used. When you end up returning the object of that type from some other function, instead of creating a local copy, and then copying it for the return, it'll just generate code in the called function that works directly in the collection in the calling function, so the return basically becomes a nop. As a result, instead of the horribly inefficient copying that it looks like, you end up with a really fast return with no copying at all.
(1) The stack is actually only local to expressionParser so I KNOW I can remove the new keyword
correct
(2) Do I HAVE To create a pointer to the queue in this case. If I need to create the pointer, then I should call a delete output in my query function to properly get rid of the queue?
correct. Here, "creating pointer" doesn't mean again using new and copy all contents. Just assign a pointer to the already created queue<string>. Simply delete output; when you are done with it in your query().
(3) vector being returned by query. Should that be left as I have it or should it be a pointer and what's the difference between them?
I would suggest either you pass the vector<Line*> by non-const reference to your query() and use it or return a vector<Line*>* from your function. Because difference is, if the vector is huge and return by value then it might copy all its content (considering the worst case without optimization)
(4) Once I consume that vector (display the information in it) I need it to be removed from memory, however, the pointers contained in the vector are still good and the items being pointed to by them should not be deleted. What's the best approach in this case?
Pass the vector<Line*> into the function by reference. And retain it in scope until you need it. Once you are done with pointer members 'Line*inside it, justdelete` them
(5) What happens to the contents of containers when you call delete on the container? If the container held pointers?
Nothing happens to the pointer members of the container when it's deleted. You have to explicitly call delete on every member. By the way in your case, you can't delete your vector<Line*> because it's an object not a pointer & when you delete output;, you don't have to worry about contents of queue<> because they are not pointers.
(6) Those pointers are deleted won't that affect other areas of my program?
Deleting a valid pointer (i.e. allocated on heap) doesn't affect your program in any way.
You got a logic problem here - a std::vector (or any container for that matter) of pointers will, at destruction, only kill those pointers, not what they point to. So the following is perfectly fine:
#include <vector>
#include <iostream>
std::vector<int*> GetIntPtrVec(){
std::vector<int*> ret(10); // prepare for 10 pointer;
for(int i=0; i<10; ++i){
ret[i] = new int(i);
}
}
int main(){
std::vector<int*> myvec = GetIntPtrVec(); // copies the return into myvec
// ^^^^^^^^^^^^^^^^^^^^^^
for(int i=0; i<myvec.size(); ++i){
// display and delete again
std::cout << myvec[i] << "\n";
delete myvec[i];
}
std::cin.get();
}
When returning a vector from a function, it gets copied into the receiving variable (marked by the ^ above).
Then for the pointer-to-vector approach, of course you need to delete that pointer again sometime - when you can be sure that nobody uses it anymore. But that same problem also applies for the first approach - when are you gonna delete the pointers inside the returned vector? You have to make sure that there are no dangling pointers, e.g. pointer, which point to your now deleted memory.

Variable Scoping in a method and its persistence in C++

Consider the following public method that adds an integer variable to a vector of ints(private member) in a class in C++.
KoolMethod()
{
int x;
x = 10;
KoolList.Add(x);
}
Vector<int>KoolList;
But is this a valid addition to a vector ??? Upon calling the method, it creates a local variable. The scope of this local variable ends the moment the execution control leaves the method. And since this local variable is allocated on a stack(on the method call), any member of KoolList points to an invalid memory location in deallocated stack which may or may not contain the expected value of x. Is this an accurate description of above mechanism ??
Is there a need for creating an int in heap storage using "new" operator everytime a value needs to be added to the vector like described below ????:
KoolMethod()
{
int *x = new int();
*x = 10;
KoolList.Add(x);
}
Vector<int*>KoolList;
But is this a valid addition to a vector?
Yes, a (standard library) vector stores copies.
Is there a need for creating an int in heap storage using "new" operator
If you don't want the objects to be copied or to work with polymorphic objects (see object slicing) you'd use pointers. In that case you should preferably avoid dealing with deallocation manually and use wrappers (smart pointers or pointer containers) though to get exception safety back.
A Vector<int> (at least if it is std::vector) stores elements by value, so calls to add() creates a copy of the parameter object and stores that copy into the array. Therefore it doesn't matter what happens with the original object, the copy within the vector is alive as long as the vector itself (unless removed or overwritten explicitly, of course).
A Vector<X*> may be more appropriate if you
want to work with polymorphic X objects,
don't want to copy objects of X e.g. because it's expensive or disallowed,
want to share the same objects between different parties.
Of course, none of these applies to int, only to real objects. Still, it is better to store smart pointers in the vector instead of raw pointers, e.g. vector<auto_ptr<X> > or vector<shared_ptr<X> >. These automatically manage the disposal of objects for you.
If you create a vector of ints, it will not be a vector of pointers. The integers are stored by value, no pointers involved, and therefore you won't run into any problems with invalid memory addresses.
Here's an example of code that would cause such a problem:
std::vector<int *> my_list;
void a_method() {
int value = 2; // allocated on the stack
my_list.push_back(&value); // pushes a pointer to the stack... not good
}
Think about this: adding to the standard vector creates copy of added object.
In the first code snippet, you use vector of ints, so you'll add the copy of local int and everything is fine.
In the second code snippet you use vector of pointers to int, so you'll add the copy of a pointer (not the copy of the object this pointer is pointing to). Since the object pointed by the pointer will be still valid after leaving the method (it's initialized using new operator and it's not deleted anywhere) everything will be fine too.