I want to understand whether in this piece of code, pointers stored in the vector by func() are valid when accessed from main_func(), and if so why?
void func(vector<double*>& avector) {
double a=0,b=0;
for (int i=0;i<10;i++) {
double *a = new double[2];
avector.push_back(a);
avector[avector.size()-1][0] = a;
avector[avector.size()-1][1] = b;
}
}
void main_func(){
vector<double*> v;
func(v);
for (int i=0;i<v.size();i++)
{
// access a
// References stored in vector valid???
}
}
Why don't you use a vector of pair vector<pair<double,double>>
http://www.cplusplus.com/reference/utility/pair/
Let's get to basics. A pointer is simply four-byte integer value denoting address in memory in which some data exists. Dynamic memory allocation is application-global, so if you allocate memory anywhere in your program by new, new[] or malloc (or something like this), you can use this memory anywhere you like and OS guarantees, that it won't be moved anywhere (in terms of address, that you got from the memory allocation routine).
So let's get back to your program. You allocate some memory inside the function and store the addresses of pointers to that memory in the vector. When you exit that function, these pointers are still completely valid and you can use them as you wish.
Don't forget to free them, when you don't need them anymore!
They are valid because you created them with new and that means they have dynamic storage duration. You do however lack the corresponding delete and therefore have a memory leak.
Your vector does not store references, but pointers to objects on the heap. That object is an array of two doubles, and you just copy the values from your local variable. So everything is alright (except that you don't release the memory).
If you somewhere (store and) return references or pointers to function locals, those won't have any meaning outside the function.
Related
I was thinking about a this situation not for a real implementation but to understand better how pointers works.
class foo(){
foo();
~foo();
void doComplexThings(const std::vector<int*>& v){
int* copy;
for(int i = 0; i < v.size(); i++){
copy = v[i];
// do some stuffs
}
}
}
main(){
std::vector<int*> myVector; // suppose we have 100 elements
doComplexThings(myVector);
for(int i = 0; i < myVector.size(); i++){
delete myVector[i];
}
myVector.clear();
}
Ok, I know that have no sense to copy v[i] inside an other pointer, but I was thinking: copy do a memory leak?
After the execution of doComplexThings(), copy will continue to exist and will occupy space in the heap?
After deleting all elements it will continue to exist and point to a deallocated memory?
So logically if I do this things with complex objects I'll keep occupy the memory with unreference object? Or copy is saved in the stack because I don't use new? And at the end of doComplexThings it will be deleted?
I'm a bit confused, thanks!
There is some confusion on the topic of pointers in the C++ community. While it is true that smart pointers have been added to the library to alleviate problems with dynamic memory allocation, raw pointers are not obsolete. In fact, whenever you want to inspect another object without owning it, you should use a reference or raw pointer, depending on which suits your needs. If the concept of ownership is unclear to you, think of an object as being owned by another object if the latter is responsible for cleaning up afterwards (deleting the former).
For example most uses of new and delete should be replaces with the following (omitting std for brevity):
{
auto ptr_to_T = make_unique<T>(//constructor params);
do_stuff_with_smart_ptr(ptr_to_T);
do_stuff_with_T(*ptr_to_T);
do_stuff_with_raw_ptr(ptr_to_T.get());
} // automatic release of memory allocated with make_unique()
Notice how a function that takes a T* doesn't need a smart pointer if it doesn't keep a copy of the T* it is given, because it doesn't affect the lifetime of the object. The object is guaranteed to be alive past the return point of do_stuff_with_T() and its function signature signals that it doesn't own the object by taking a raw pointer.
On the other hand, if you need to pass the pointer to an object that is allowed to keep the pointer and reference it later, it is unclear when the object will need to be destroyed and most importantly by whom. This is solved via a shared pointer.
ClassThatNeedsSharedOwnership shared_owner;
{
auto ptr_to_T = make_shared<T>(//constructor params);
shared_owner.set_T(ptr_to_T);
// do a lot of stuff
}
// At this point ptr_to_T is destroyed, but shared_owner might keep the object alive
So how does the above factor in to your code. First of all, if the vector is supposed to own (keep alive) the ints it points to, it needs to hold unique_ptr<int> or shared_ptr<int>. If it is just pointing to ints held by something else, and they are guaranteed to be alive until after the vector is destroyed, you are fine with int*. In this case, it should be evident that a delete is never necessary, because by definition your vector and the function working on the vector are not responsible for cleaning-up!
Finally, you can make your code more readable by changing the loop to this (C++11 which you've tagged in the post):
for (auto copy : v){
// equivalent to your i-indexed loop with copy = v[i];
// as long as you don't need the value of i
do_stuff_to_int_ptr(copy);
// no delete, we don't own the pointee
}
Again this is only true if some other object holds the ints and releases them, or they are on the stack but guaranteed to be alive for the whole lifetime of vector<int*> that points to them.
No additional memory is allocated on the heap when you do this:
copy = v[i];
variable copy points to the same address as v[i], but no additional array is allocated, so there would be no memory leak.
A better way of dealing with the situation is to avoid raw pointers in favor of C++ smart pointers or containers:
std::vector<std::vector<int>> myVector;
Now you can remove the deletion loop, which is an incorrect way of doing it for arrays allocated with new int[length] - it should use delete[] instead:
delete[] myVector[i];
Basically you're illustrating the problem with C pointers which lead to the introduction of C++ unique and shared pointers. If you pass a vector of allocated pointers to an opaque member function, you've no way of knowing whether that function hangs onto them or not, so you don't know whether to delete the pointer. In fact in your example you don't seem to, "copy" goes out of scope.
The real answer is that you should only seldom use allocated pointers in C++ at all. The stl vector will serve as a safer, easier to use version of malloc / new. Then you should pass them about as const & to prevent functions from changing them. If you do need an allocated pointer, make one unique_ptr() and then you know that the unique_ptr() is the "owner" of the memory.
I have been pondering an issue today and it's difficult to find the answer on google.
I'm trying to understand the STL container behaviour when dealing with pointers to both objects allocated on the heap, and on the stack.
So, start with objects, no pointers ... imagine I have ...
std::vector<int> myVec;
while(true)
{
int myInt = 5;
myVec.push_back(myInt);
myVec.pop_back();
}
My understanding is that the pop_back() method will ensure the integers contained in the vector are deleted, not just removed from the container. So if this ran and did a billion iterations, I should not expect to leak memory. Everything I insert, will be deleted. A memory check shows this behaviour.
Now consider I use a vector of pointers (to objects on the heap) ...
std::vector<int*> myVec;
while(true)
{
int * myIntP = new int(5);
myVec.push_back(myIntP);
myVec.pop_back();
}
In this case, only the pointer itself ought to be removed each time pop_back() is called, and the underlying object remains un-deleted, causing a memory leak. So after a billion iterations I have quite some significant memory being used, even though I have no entries in my vector.
Now what if I have a vector of pointers (to objects on the stack) ...
std::vector<int*> myVec;
while(true)
{
int myInt = 5;
int * myIntP = &myInt;
myVec.push_back(myIntP);
myVec.pop_back();
}
Here the pointers point to stack objects. Is their memory freed in the call to pop_back(), or not? A memory check showed me that this behaviour was no memory leaked. The small amount of memory used, indicated that this behaved like objects on the stack. However this was not expected to me, because if the pointer had been passed into me from another function, to a stack variable i.e.
void myFunc(int * myIntP)
{
std::vector<int*> myVec;
myVec.push_back(myIntP);
myVec.pop_back();
}
int main()
{
int myInt = 5;
int * myIntP = &myInt;
myFunc(myIntP);
std::cout << (*myIntP) << std::endl;
return 0;
}
Then allowing the vector to free this memory, would render my myIntP pointing to removed data. So surely this can't be correct?
Could anyone help explain?
Also is there a name for "a pointer pointing to a variable on the stack" i.e. not initialised with "new"?
Thanks
Joey
while(true)
{
int myInt = 5;
int * myIntP = &myInt;
myVec.push_back(myIntP);
myVec.pop_back();
}
You only actually have one int here, myInt with a value of 5. The loop will re-use the same one. You push a pointer to that one int into the vector and then remove it. Nothing else is happening. There isn't a memory leak because you are not allocating new ints.
STD containers do nothing different for pointers than they would for a 32/64 bit interger. As far as they care, a pointer is just another number. So, if you insert a pointer into a container, it is your responsibility to delete it.
If you make a pointer to a variable on the stack, the variable will be destructed when it goes out of scope, regardless of the pointer. And destructing the pointer (as long as you don't call delete on it) will have no effect on the variable.
So if you stop using your pointer before, no problem, if you store it longer, problem...
And if you plan on using pointers on dynamically allocated variable, you should look into smart pointers.
Here the pointers point to stack objects. Is their memory freed in the call to pop_back(), or not?
No, they are not. They are freed when they go out of scope, which happens at the }. After the }, the memory is no longer used for this variable (the stack-frame popped off) and will be reused! So if you didn't pop-off the pointer right after pushing it, your vector would contain a dangling pointer when the variable goes out of scope.
So, let's go through each of your examples:
std::vector<int> myVec;
while(true)
{
int myInt = 5;
myVec.push_back(myInt);
myVec.pop_back();
}
The push_back() method makes a copy of the argument and stores the copy internally. So, if you were storing an stack-allocated object instead of a primitive, a copy constructor would have been called. The pop_back() method does not assume anything either. It removes the copy of the item you stored (whether it was a value or a pointer) and removes it from its internal storage. If the copy stored was a stack-allocated object, the class' destructor will be called when the container manages its internal memory because the copy item will no longer be in scope.
Your second example:
std::vector<int*> myVec;
while(true)
{
int * myIntP = new int(5);
myVec.push_back(myIntP);
myVec.pop_back();
}
As you stated, the integer is allocated on the heap. Calling push_back() still stores the argument. In this case, you are not storing the value of the integer "5", the value of the pointer, an address of a memory location that contains the value of "5". Since you allocated the memory that stores the "5", you are responsible for getting that pointer and deallocate the memory. The pop_back() method does not delete the pointer for you nor returns you a copy of the pointer.
Your third example has subtle differences:
std::vector<int*> myVec;
while(true)
{
int myInt = 5;
int * myIntP = &myInt;
myVec.push_back(myIntP);
myVec.pop_back();
}
In this case, you are not allocating any memory on the heap. You assigning the address of myInt, which is a stack-allocated value, to a pointer. Stack memory lives through out the life of a process and does not deallocate on its own. However, once you leave the current scope (the while loop), the memory reused by something else. The memory is still there, but it may no longer have the value you expect.
Your last example:
void myFunc(int * myIntP)
{
std::vector<int*> myVec;
myVec.push_back(myIntP);
myVec.pop_back();
}
int main()
{
int myInt = 5;
int * myIntP = &myInt;
myFunc(myIntP);
std::cout << (*myIntP) << std::endl;
return 0;
}
You were expected the memory for myInt to be dealloated after making myFunc() was called. However, container methods do not modify the supplied values. They copy them. When myFunc() pushed the myIntP pointer, it is pushing the pointer, the address of what myIntP points to, not the value in memory of that address. You would have to dereference the pointer, using call:
myVec.push_back(*myIntP);
Note that even if you did this, containers copy the value. So, myInt is still unaffected.
You are confusing and conflating "destruction" and "deletion" -- they are NOT the same thing, but are two different concepts in C++.
Deletion can only happen with pointers -- if you try to delete a non-pointer, you'll get a compile-time error. Deletion first destroys the pointed at object and then returns the memory for it to the heap.
Destruction on the other hand can happen with anything, but is mostly only of interest with classes, where it calls the destructor. With any type that has no destructor (such as int or any raw pointer type), destruction does nothing. While you CAN destroy an object manually, you pretty much never do -- it happens automatically for you when something else happens. For example, when a local variable goes out of scope, it is destroyed.
So in your code above, what happens? Well you have a local std::vector which is destroyed when it goes out of scope. Its destructor will delete anything it allocated internally, and destroy all the elements of the vector. It will NOT however, delete any elements of the vector. When you have vector<int>, that's all there is, since nothing else was allocated, but when you have a vector<int *>, if those pointers were allocated, they'll leak. If they weren't allocated (if they point at locals), there's nothing to leak.
I think you need to learn deep the scope variable validity
exemple :
{
int myVar;//Construct myVar on the stack
}//At this point, myVar is deleted with the stack
in your last exemple, you declare myInt at the start of main and don't do anything on value in myFunc.
It's normal to don't lose myInt data. it will be erase after the return 0;
I have a fairly simple question;
I have arrays which contain pointers to objects. I sometimes create mutated arrays from those arrays and only use them, let's say, within a method. Aftwards I don't need them. In this case I don't want the pointed data to be destroyed as I keep using the original Array. What I don't fully understand is what happens to the pointers ( not the data itself, but the pointers) that were created in my temporarily Array? How does Memory deal with them. As far as I know Pointers can only point to an address. You can't "delete" them.
Anyone who can give me more insight? All this time I feel like I'm doing something wrong with memory.
In this case list is my "bag", which is an object wrapper for an array implementation. However since it contains gabs between indexes I use getGapless to get a bag where the nullptr indexes are excluded.
I delete my bag at the end, but it doesn't delete the actual content ( that is done with a different method ).
So when do those pointers in my "players" bag go out of scope?
virtual void processEntities(artemis::ImmutableBag<artemis::Entity*>& bag)
{
artemis::Bag<artemis::Entity*> * list = (artemis::Bag<artemis::Entity*>*)this->world->getGroupManager()->getEntities("HUMAN");
if(list == nullptr) return;//Kill function
artemis::Bag<artemis::Entity*> * players = list->getGapless();
for(int i=0; i<players->getCount(); i++)
{
for(int j=i+1; j < players->getCount(); j++)
{
if(intersects(*players->get(i),*players->get(j))){
std::cout << "Collide YEAH \n";
}
}
}
delete players;
}
Nope, don't worry! You can think of pointers as being managed in the same way as ints or doubles (at least in terms of memory). The pointer itself is like an int that happens to contain the address of some other object or array of objects. Once the pointer disappears from scope, the memory for the pointer itself will automatically be recovered.
The exception would be if you're doing something like int** p = new int*[1], i.e. creating pointers with new. Then you will at some point need to delete p.
If you're creating your pointers like int* p = new int[size]; (which is probably what you want), then p itself is on the stack, which means you don't need to concern yourself with memory deallocation, but the array p points to is on the heap which means you will need to deallocate it at some point.
Pointers are ordinary variables. They are not handled in any special way. There's no difference between pointer variables and integer variables in that respect, as there's no difference between between pointer arrays and integer arrays in that respect.
The memory management for all variables in the language is entirely up to you. If you declare a local variable, it is automatically destroyed when control goes out of its block. If you allocate/create objects dynamically, then you have to deallocate/destroy them explicitly. And so on. There's absolutely nothing special about pointers. They are just like any other variables.
Basically, it is not clear why you are even asking this question, since the issue your question seems to address does not really exist. Can you provide an example of what caused you to ask this?
Pointers just hold addresses, the same way 'int' holds an integer. If you instead had an array of ints and you were using a mutated array based on it, then got rid of the mutated array, the original array stays untouched; here it is really no different.
The values in the mutated array go away, but since they are copies (regardless of whether they are ints or pointers or whatever), it does not affect the original.
In C++, how does a function treat memory that has been dynamically allocated upon exiting the scope of the function? Is this memory cleared, or can it be passed back into the main block?
In context: I have a function, and I pass it a pointer to double to serve as an array. I dynamically allocate this memory within the function, initialise the elements and the exit the function.
void my_func(double* ptr){
ptr = new double[2];
ptr[0] = 15; ptr[1] = 10;
}
In the main block, I then use the newly allocated array.
int main(){
double* ptr;
my_func(ptr);
cout << ptr[0] + ptr[1] << endl;
delete[] ptr;
return 0;
Will this work? Are there dangers/pitfalls associated with this approach?
In C++, how does a function treat memory that has been dynamically allocated upon exiting the scope of the function? Is this memory cleared, or can it be passed back into the main block?
In C++, memory that has been manually (dynamically) allocated has to be manually deallocated.
In context: I have a function, and I pass it a pointer to double to serve as an array. I dynamically allocate this memory within the function, initialise the elements and the exit the function.
You are taking the pointer by value, so while you can change the contents of what the pointer points to you cannot change the pointer itself. Doing so changes only the local copy of the pointer. If you take the pointer by reference, then it would work:
void my_func(double*& ptr)
{
ptr = new double[2];
ptr[0] = 15; ptr[1] = 10;
}
Will this work? Are there dangers/pitfalls associated with this approach?
It will mostly work, but its not the way to go in C++ because of the associated pitfalls. Better go with a vector:
std::vector<int> my_func()
{
std::vector<int> buffer;
buffer.push_back(15);
buffer.push_back(10);
return buffer;
}
Will this work? Are there dangers/pitfalls associated with this approach?
It may work as long as nothing goes wrong. If an exception gets thrown, it'll generally leak memory. To avoid that, you generally want to free the memory in the destructor of some class, then create an instance of that class with automatic storage duration. That means it'll be destroyed when it goes out of scope, and will (in turn) release the memory it's controlling.
The standard library already has a variety of containers to do that. What you have is closest to a std::vector, but there are also std::deque, std::list etc.
Below, I'm not declaring my_ints as a pointer. I don't know where the memory will be allocated. Please educate me here!
#include <iostream>
#include <vector>
class FieldStorage
{
private:
std::vector<int> my_ints;
public:
FieldStorage()
{
my_ints.push_back(1);
my_ints.push_back(2);
}
void displayAll()
{
for (int i = 0; i < my_ints.size(); i++)
{
std::cout << my_ints[i] << std::endl;
}
}
};
And in here, I'm declaring the field my_ints as a pointer:
#include <iostream>
#include <vector>
class FieldStorage
{
private:
std::vector<int> *my_ints;
public:
FieldStorage()
{
my_ints = new std::vector<int>();
my_ints->push_back(1);
my_ints->push_back(2);
}
void displayAll()
{
for (int i = 0; i < my_ints->size(); i++)
{
std::cout << (*my_ints)[i] << std::endl;
}
}
~FieldStorage()
{
delete my_ints;
}
};
main() function to test:
int main()
{
FieldStorage obj;
obj.displayAll();
return 0;
}
Both of them produces the same result. What's the difference?
In terms of memory management, these two classes are virtually identical. Several other responders have suggested that there is a difference between the two in that one is allocating storage on the stack and other on the heap, but that's not necessarily true, and even in the cases where it is true, it's terribly misleading. In reality, all that's different is where the metadata for the vector is allocated; the actual underlying storage in the vector is allocated from the heap regardless.
It's a little bit tricky to see this because you're using std::vector, so the specific implementation details are hidden. But basically, std::vector is implemented like this:
template <class T>
class vector {
public:
vector() : mCapacity(0), mSize(0), mData(0) { }
~vector() { if (mData) delete[] mData; }
...
protected:
int mCapacity;
int mSize;
T *mData;
};
As you can see, the vector class itself only has a few members -- capacity, size and a pointer to a dynamically allocated block of memory that will store the actual contents of the vector.
In your example, the only difference is where the storage for those few fields comes from. In the first example, the storage is allocated from whatever storage you use for your containing class -- if it is heap allocated, so too will be those few bits of the vector. If your container is stack allocated, so too will be those few bits of the vector.
In the second example, those bits of the vector are always heap allocated.
In both examples, the actual meat of the vector -- the contents of it -- are allocated from the heap, and you cannot change that.
Everybody else has pointed out already that you have a memory leak in your second example, and that is also true. Make sure to delete the vector in the destructor of your container class.
You have to release ( to prevent memory leak ) memory allocated for vector in the second case in the FieldStorage destructor.
FieldStorage::~FieldStorage()
{
delete my_ints;
}
As Mykola Golubyev pointed out, you need to delete the vector in the second case.
The first will possibly build faster code, as the optimiser knows the full size of FieldStorage including the vector, and could allocate enough memory in one allocation for both.
Your second implementation requires two separate allocations to construct the object.
I think you are really looking for the difference between the Stack and the Heap.
The first one is allocated on the stack while the second one is allocated on the heap.
In the first example, the object is allocated on the stack.
The the second example, the object is allocated in the heap, and a pointer to that memory is stored on the stack.
the difference is that the second allocates the vector dynamically. there are few differences:
you have to release memory occupied by the vector object (the vector object itself, not the object kept in the vector because it is handled correctly by the vector). you should use some smart pointer to keep the vector or make (for example in the destructor):
delete my_ints;
the first one is probably more efficient because the object is allocated on the stack.
access to the vector's method have different syntax :)
The first version of FieldStorage contains a vector. The size of the FieldStorage class includes enough bytes to hold a vector. When you construct a FieldStorage, the vector is constructed right before the body of FieldStorage's constructor is executed. When a FieldStorage is destructed, so is the vector.
This does not necessarily allocate the vector on the stack; if you heap-allocate a FieldStorage object, then the space for the vector comes from that heap allocation, not the stack. If you define a global FieldStorage object, then the space for the vector comes from neither the stack nor the heap, but rather from space designated for global objects (e.g. the .data or .bss section on some platforms).
Note that the vector performs heap allocations to hold the actual data, so it is likely to only contain a few pointers, or a pointer and couple of lengths, but it may contain whatever your compiler's STL implementation needs it to.
The second version of FieldStorage contains a pointer to a vector. The size of the FieldStorage class includes room for a pointer to a vector, not an actual vector. You are allocating storage for the vector using new in the body of FieldStorage's constructor, and you leaking that storage when FieldStorage is destructed, because you didn't define a destructor that deletes the vector.
First way is the prefereable one to use, you don't need pointer on vector and have forgot to delete it.
In the first case, the std::vector is being put directly into your class (and it is handling any memory allocation and deallocation it needs to grow and shrink the vector and free the memory when your object is destroyed; it is abstracting the memory management from you so that you don't have to deal with it). In the second case, you are explicitly allocating the storage for the std::vector in the heap somewhere, and forgetting to ever delete it, so your program will leak memory.
The size of the object is going to be different. In the second case the Vector<>* only takes up the size of a pointer (4bytes on 32bit machines). In the first case, your object will be larger.
One practical difference is that in your second example, you never release either the memory for the vector, or its contents (because you don't delete it, and therefore call its destructor).
But the first example will automatically destroy the vector (and free its contents) upon destruction of your FieldStorage object.