Converting vector to array. How to deallocate memory? - c++

I am converting a vector of doubles to an array of doubles as seen here:
The difference is, that I want to return the pointer a as a function parameter:
void getArray(double* a)
{
std::vector<double> v;
a = &v[0];
}
So my question is, when does the memory of a gets deallocated? Or do I have to call delete[] a by myself, which seems strange since I did't allocate the memory with new. I have read the comments to the above mentioned answer but it still isn't clear to me.

The memory pointed to by a gets deallocated when the vector v is destructed. In this case, that's at the end of the function getArray.

This implementation would invoke undefined behavior because v is local:
void getArray(double* a)
{
std::vector<double> v;
a = &v[0]; // would be a UB for returning the pointer to internals of a local variable.
}
However, the caller will never see any effect of this, because modifications to a stay local to getArray function.
If you want to make an array out of a vector, allocate a new array, use std::copy to copy the content into it, and return the array to the caller. Make sure the callers call delete[] on the result once they are done with the copyL
double *getArray(const vector<double>& v) {
double *res = new double[v.size()];
std::copy(v.begin(), v.end(), res);
return res;
}
The caller should use it as follows:
vector<double> data;
data.push_back(...);
... // populate the vector
double *tmp = getArray(data);
... // Use the array
delete[] tmp; // Avoid memory leaks

Don't do this:
void getArray(double* a)
{
std::vector<double> v;
a = &v[0];
} // The vector is destroyed here, and the memory
// is deallocated.
In any case, you're not modifying the a pointer outside of your function, so you won't get the desired effect.
Instead, return the vector and use it directly. Or, in general, use vectors throughout your code. If you need to pass them in to a function that expects a pointer to an array, you can pass &v[0] there. Such a function usually expects the size too. For this, pass v.size(). You can do this safely as long as that function doesn't take ownership, or deallocate the memory.
Note, also, that a vector declared as std::vector<double> v; does not have a size, so attempting to access the first element, as in v[0] is also undefined behaviour. At the very least, you need to give the vector a size (pass a size to its constructor) to ensure some memory is allocated. You should always make sure the vector has some allocated memory before indexing into it, including when trying to take the address of the first element.
What you probably want to do is:
std::vector<double> getArray() {
std::vector<double> v = /* some sane initialisation */;
return v;
}
// some time later, assuming a function:
// void do_something(double* a, size_t n);
// ...
std::vector<double> v = getArray();
if (v.size()) {
do_something(&v[0], v.size());
} else {
// fail gracefully
}

when does the memory of a gets deallocated?
The a pointer itself is a local variable, so it is deallocated at the end of its scope.
a points to the memory allocated by the vector v. The pointed memory is deallocated in the destructor of v (The memory may also be deallocated if objects are added to or removed from the vector). And because v is a local variable, it is destroyed at the end of scope.
Or do I have to call delete[] a by myself,
No, because the memory is owned by the vector object, but also because
which seems strange since I did't allocate the memory with new.
Exactly. You didn't call new[], so you don't call delete[].
Note that v[0] has undefined behaviour because the vector is empty.

Related

C++ Is it a memory leak? Pointer to array alocated dynamicaly in another function

Quick question. Will this leak and why/ why not?
int main()
{
int array[] = {1,2,3};
doStuff(array);
return 0;
}
when doStuff will do something like this
void doStuff(int * arr)
{
// ...
arr = new int [50];
// ...
}
EDIT for #Scott Hunter
I think it won't leak because array points to memory on stack and I've never heard of memory leaking from stack, but on the other hand i kinda lose any link to this memory.
EDIT2
My problem was I was thinking that changing arr in doStuff address will change array in main as well but it won't.
Yes it will leak, since you don't call delete [] arr; anywhere inside of doStuff().
Note that you don't even change the int array[]; declared outside of the function.
All you are doing is to change a copy of that pointer that was passed as by value parameter.
As an aside recommenation:
Don't use raw pointers and raw arrays in c++. Rather use a std::vector<int> for your case, and forget about dynamic memory management at all.
doStuff takes a copy of the array pointer. Setting arr to something else inside the body of doStuff will not modify the original array value in main.
Therefore, unlesss you call delete[] arr inside doStuff, your code will leak.

C++ Containers of pointers

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;

Array as return value of a function

Is there a way to return an array as a result of a function in c++?
int* returnArray()
{
int* arr = new int[3];
return arr;
}
This way arr is a local variable and the alocated memory block is lost after the function returns.
Is there any way around this besides defining an array outside the function block?
Allocated memory block is not lost, since the memory is allocated on the heap. The pointer to this memory is copied, and correctly returned to the caller. In other words, there is nothing wrong with your code - except possibly for the fact that the caller must know the array size in order to do anything useful with the returned array.
The anti-pattern you are probably referring to looks like this:
// WRONG: returns pointer to local data
int* returnArray() {
int arr[3] = {1, 2, 3};
return arr;
}
This is an error because arr is allocated on the stack, and the function returns a pointer to that data. To fix it, one would need to declare the function as returning an array, but C++ doesn't allow this, so it must be done indirectly. Fixed function would then look like this:
struct Array {
int array[3];
};
// correct: generated copy constructor correctly copies arr
Array returnArray() {
Array arr = {{1, 2, 3}};
return arr;
}
In production code, and if you can use C++11, your function would simply return std::array<int, 3>. C-style arrays are almost always used in low-level code to implement containers and there is almost never a need to directly return them from functions.
You're returning a pointer to an array it's OK, but the problem is "who is responsible to delete it", you can use smart pointers:
std::unique_ptr<int[]> returnArray()
{
std::unique_ptr<int[]> arr (new int[3]);
return arr;
}
And everyone is happy. Also, you can use std::vector.
std::vector<int> returnArray()
{
std::vector<int> arr(3);
return arr;
}
Your function is okay as is. Memory obtained with a new expression is never deallocated until you use a delete expression.
This is the version that would lose the memory when the function returns:
// WRONG:
int* returnArray()
{
int arr[3];
return arr;
}
The even better way would be to return a std::vector<int>.
What you have works; the issue is that you've made the caller responsible for remembering to delete the dynamic array. This is a good recipe for a memory leak.
Perhaps you were thinking of trying to return a local array:
int * returnArray() {
int arr[3];
return arr; // BOOM! dangling pointer
}
This is wrong, since this array is destroyed when the function returns; using the pointer after that will give undefined behaviour.
To solve both issues, return a managed dynamic array:
std::vector<int> returnVector() {
std::vector<int> v(3);
return v;
}
Actually, you're code is fine but dangerous, I mean, allocated memory for arrremains until you call delete[] on it, meaning that you can safely access array's elements but delegating memory clean up to source code using this method is a bad practice and will, most probably, lead to a memory leak or corruption.
I would recommend passing the array as a parameter so calling code is in charge of memory management:
void returnArray(int* arr)
{
... Your code here managing array's contents ...
}
Or, if this is one class' method, manage this memory from inside this class.
Edit: Or better, use smart pointers as suggested by #M M.

Pointers assigned inside an invoked function valid?

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.

std::vector Destruction and Unexpected Memory Leak

Consider the following example:
#include <vector>
class Foo {
std::vector<int*> v;
public:
Foo() {
this->v.push_back(new int(23));
this->v.push_back(new int(24));
this->v.push_back(new int(25));
}
~Foo() {
}
};
int main() {
Foo f;
return 0;
}
When f goes out of scope in main(), f's destructor is called, which should indirectly free f.v. According to this, the destructor of each element of the vector v should now be called.
However, when I run this program in valgrind, I find that the int*'s were not deallocated.
$ valgrind --leak-check=full ./a.out
What am I missing here?
std::vector<T> does indeed call the destructor of T when it is destroyed. Here T is int *. The destructor of int * does nothing. The storage for the int * itself is freed, but the ints they point to are not.
Consider:
int main() {
int *x = new int(23);
return 0;
}
This exhibits the same problem; when x goes out of scope, its destructor is indeed called, and the storage for the pointer that is x is freed, but since the destructor of a pointer is a no-op, the pointed-to int is not freed.
More to the point, vector doesn't know how the ints were allocated. They might be allocated by new int, but they could also point to elements inside an array allocated with new int[200], or they might point to malloc'd data, or they might point into a mmap'd buffer, or they might point to struct elements, or two vectors might be pointing to the same ints... etc. vector isn't smart enough to divine what you want done with these, and so it leaves them alone (additionally, giving vector logic to delete pointed-to elements would break vectors of non-pointer elements such as std::vector<int>, as you can't delete an int!)
You need to either use a std::vector<int>, or use a smart pointer in conjunction with it, eg std::vector<boost::shared_ptr<int> >. Note that using smart pointers may add overhead; with C++0x you should be able to use std::vector<std::unique_ptr<int>> in conjunction with std::move to avoid this overhead. Boost also has pointer vectors that free the pointed-to elements as you expected as well.
The destructor of each element of the vector v should now be called
Yes: the int* objects stored in the vector are destroyed (which is effectively a no-op). The objects pointed to by the pointers in the container are not destroyed.
Consider the following, equally valid program:
{
int x;
std::vector<int*> v;
v.push_back(&x);
} // x cannot be delete'd because it isn't dynamically allocated.
You should use a smart pointer, like std::unique_ptr or shared_ptr so that you don't have to worry about the memory management (do not use std::auto_ptr; it is incompatible with the Standard Library containers because it isn't really copyable). If you don't use a smart pointer then you need to destroy the dynamically objects yourself; doing this correctly is rather difficult.
Each element of your vector is an int *. When an int * is destroyed, the language does not automatically call delete on it. In other words, it's the pointer being destroyed, not the pointee.
Since you are using the new keyword, the integers are being allocated on the heap rather than the stack. In other words, they are being allocated dynamically. In other words, you need to clean up after it.
The "destructor" for a pointer type is to simply delete that pointer. It does not touch the data which is located at the memory address stored by the pointer. Consider the following example:
int a = 5;
int* i = &a;
if (true)
{
int* j = i;
} //j goes out of scope, should *i and a be deleted? no.
So you will need to do this in the destructor:
std::vector<int*>::iterator iter;
for (iter = v.begin(); iter != v.end(); iter++)
{
delete *iter;
}