Dynamic allocated array is not freed - c++

I'm using the code above to dynamically allocate an array, do some work inside the function, return an element of the array and free the memory outside of the function. But when I try to deallocate the array it doesn't free the memory and I have a memory leak. The debugger pointed to the myArray variable shows me the error CXX0030. Why?
struct MYSTRUCT
{
char *myvariable1;
int myvariable2;
char *myvariable2;
....
};
void MyClass::MyFunction1()
{
MYSTRUCT *myArray= NULL;
MYSTRUCT *myElement = this->MyFunction2(myArray);
...
delete [] myArray;
}
MYSTRUCT* MyClass::MyFunction2(MYSTRUCT *array)
{
array = (MYSTRUCT*)operator new(bytesLength);
...
return array[X];
}

The only time you should use delete[] is when you've allocated with new[], but that's not what you're doing. You're using operator new, which isn't what you should use for general-purpose array allocation. Use new[] instead. Or use a vector.
Furthermore, although you pass myArray to MyFunction2 as array and then assign a new value to array inside the function, that doesn't change the value of myArray in the caller. That variable retains its original null value, so your delete[] call does nothing. You can change array to be passed by reference instead of by value so changes to it will be reflected in its actual parameter in the caller.

You allocate the array in MyFunction2, but you don't return its address. The argument to MyFunction2 is by value, so you pass a copy of myArray to it when you call it, but the function itself can never change the value of the caller's local variable.
The simple and obvious answer to your problem is to declare the parameter of MyFunction2 to be a reference, e.g.:
MYSTRUCT* MyClass::MyFunction2(MYSTRUCT*& array)...
A much better solution, however, would be to use std::vector, and not worry about the deallocations.

You allocate the array inside of MyFunction2 and never free it. And in the MyFunction1 you delete[] the null pointer, which is a no-op. I'm not sure I can tell you what you should've done instead, because your intentions aren't clear.

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.

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.

What happens to a dynamic array (on the heap) within a struct on the stack?

My concern is whether or not the array should be deallocated. Here is an example:
typedef struct
{
int *values;
int length;
} a_struct;
void foo()
{
a_struct myStruct;
myStruct.values = new int[NUM];
delete[] myStruct.values; // Is this needed?
return;
}
My understanding is that myStruct (which is on the stack) will get deleted automatically upon the "return" statement. Does it delete "values" as well?
It does deallocate the pointer values, but not what it points to - after all, what does a_struct know about what you assigned to that pointer? Maybe it's a pointer to stuff allocated on the stack, or to an array shared with another struct.
So, yes, you need to manually deallocate it (although in modern C++ often "smart pointers" are used to manage memory).
No, it doesn't, you should delete it manually. myStruct going out of scope (and thus the myStruct.values member, i. e. the pointer being invalidated) has nothing to do with the dynamically allocated memory. The golden rule: if you call new[], always delete[] (same for new and delete).
Yes it is needed, the struct only stores the address of the array.
These days people would just store a std::vector<> (or if you just want an owning pointer to something a std::unique_ptr<>).
Nothing gets 'deleted'. The stack is popped. Period. As the struct doesn't have a destructor, nothing else happens.

Array in class constructor

For example i have class with constructor that has array of ints as parameter:
A(int* array) : m_array(array) {}
I can use it like this:
int array[] = { ... }
A a(array);
Or like this:
int* array = new int[10];
A a(array);
If object then use it array, it must (or may be not?) delete it in desctructor (if it was dynamic). But how he will know, that memory for this array was allocated dynamically?
You can't know if it's dynamically allocated or not, because after all, int* array is an int pointer, not an array. You might as well pass:
int i;
A a(&i);
As you can imagine, bad things will happen if you try to delete[] that one, or try to access m_array[N] with N > 0.
So you have to rely on the caller to do the right thing; there's nothing you can do to verify or enforce it. All you have is the address of an int. Who created that int, or how or whether more ints follow after it, will be unknown.
If you want more safety, use an std::vector. This is what it was made for.
You're initializing the array in the constructor, so it will always be initialized. It is pre-defined in the code that it will be allocated. If there are other constructors that do not allocate your array, you will need to do this check.
By the way, this is under the assumption that the array you are allocating is a member of the class. If you are assigning it to a new stack variable within the constructor, you won't be able to delete it in the destructor.
From what i understand you are trying to ask is whether the destructor will free the memory you have allocated to the array.
No, the memory you have allocated using new will have to be deleted by you either in the destructor or somewhere else the pointer is in scope as your memory allocation is not inside the constructor but outside.
You cannot know what it was because a static array decays into a pointer as well.
Basically you just need the value of the array passed to the constructor. You need not know whether it was a dynamically allocated or statically allocated array. What matters is the data member array which is part of the interface of your class and into which you are copying the data. Responsibility of the array passed to the constructor as an argument should rest with the caller regarding its deletion and lifetime.
It would make your life easier if you use std::vector instead of raw array.

C++ filling an array with numbers then returning a pointer to it

Ive been faced with a problem recently that I can't think of a good way to solve. I'm using a case structure to attempt to set attributes to a "character" that will be passed to an object constructor.
Example:
//note this is inside a function with a return type of int*
int selection;
cin >> selection;
int * iPtr;
switch(selection){
case 1:{
int anArray[6] = {8,5,2,4,250,100} // str, dex, int, luck, hp, mp
iPtr = anArray;
return iPtr;
}
//more cases and such below
The issue that I'm having is that when I return my pointer it seems to be filled with a good amount of junk, rather than the information, rather than the information that I would be expecting it to hold. Is that because the array gets destroyed at the end of the scope? If so what should I do to make this work out how I'm hoping for it to (getting a pointer with the values that I want).
Thanks!
Yes - anArray is declared on the stack. When the function exits, its stack frame is reclaimed, so it's no longer valid to refer to that memory. If you want the array to persist, allocate it on the heap instead:
int* anArray = new int[6]; // and initialize
return anArray;
Just remember to clean it up later at some point with the corresonding delete[].
EDIT
You should prefer to use something that automatically manages resources for you, like in Praetorian's answer, so that you don't accidentally leak memory.
Yes, the array you've declared is indeed local to the function and no longer exists once the function exits. You can dynamically allocate an array using new and then have the caller delete[] the memory (but don't do this!), or modify your function to return an std::unique_ptr instead of a raw pointer.
unique_ptr<int[]> anArray (new int[6]);
// do initialization
return anArray;
Now, the caller doesn't have to worry about freeing memory allocated by the function.
EDIT:
There are a couple of different ways to perform initialization of the unique_ptr.
anArray[0] = 8;
anArray[1] = 5;
// etc ...
OR
int init[6] = {8,5,2,4,250,100};
std::copy( &init[0], &init[0] + 6, &anArray[0] );
Yes, it's because the local array is overwritten as the program runs. You can either declare the array static in the method (which would be a good idea for a fixed array like this), declare it at global scope, or allocate an array with new to return. The last alternative gives you the opportunity to have a different array returned for each call, but remember to deallocate the arrays after use.
In C++, the best answer is not to return a pointer. Instead, use a proper object instead of a C array or manually allocated memory and return this object:
std::vector<int> f() {
std::vector<int> array;
// fill array
return array;
}
Using new int[x] (or whatever) is really, really deprecated in modern C++ code and is only deemed acceptable under very special circumstances. If you use it in normal code, this is a very obvious place for improvement. The same goes for other uses of manually managed memory. The whole strength of C++ lies in the fact that you don’t have to manage your own memory, thus avoiding a multitude of hard to track bugs.
Yes, it is because the array you created is created on the stack, and when you return, the part of the stack that you were at is overwritten (presumably by a debug process).
To avoid this, you would write
int* anArray = new int[6];
// fill the array
return anArray;
In this case, you will also have to delete the returned result when you are finished with it, such as in
int* dataArray = getTheArray();
// Use the dataArray
delete [] dataArray;
Allocate array on the heap
int* anArray = new int[6];
You will have to delete it manually:
delete[] iPtr;