Reputation: 2035
I think this is gonna be fairly simple for you guys.. somewhere in my program I have a memory leak.. But I can't seem to find it.. I am pretty sure its has to do with the array..
My program is intended to take a 1 integer argument, create an array of that size, and then create ANOTHER array of double that integer (all populated with random values).
So for example
input = 4
output =
54 73 18 92
52 20 67 6 14 38 87 19 77
I think I am not deleting the arrays correctly...
Heres my current code:
#include <iostream>
#include <cstdlib>
using namespace std;
int* initArray(int);
int fillArray(int *, int);
int* doubleArray(int *, int);
void displayArray(int *, int);
/*
* The program will create an array of given size
* populate the array with random number from (0-99)
* and display the array. Next, the program will double
* the size of the array, repopulate the array and
* display it again.
*/
int main(int argc, char ** argv){
if (argc != 2){
cout << "wrong number of arguments" << endl;
exit(1);
}
int n = atoi(argv[1]); // get size
srand(time(0));
// create initial array and display it
int* ptr = initArray(n);
fillArray(ptr, n);
displayArray(ptr, n);
// create the double sized array and display it
doubleArray(ptr, n);
fillArray(ptr, 2*n);
displayArray(ptr, 2*n);
}
// Create an array of size n and return its address
int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
}
// Fill array ptr with n random numbers
int fillArray(int *ptr, int n){
for(int i=0; i<n; i++){
ptr[i] = rand() % 100;
}
}
// Double the size of the array, make sure no memory leak
int* doubleArray(int *ptr, int n){
int size = 2*n;
int * tmp = new int[size];
ptr = tmp;
delete tmp;
return ptr;
}
// Display n array elements
void displayArray(int *ptr, int n){
for(int i=0; i<n; i++){
cout << ptr[i] << " ";
}
cout << endl;
}
When I run it right now, with the input of 4, my output looks like this: 34 6 4199259 1 90 6 4199259 1 88 32 94 77
The fact that some of the values are the same tells me that I am not correctly clearing the memory, and I think it has something to do with deleting the first array I clear and then deleting the second one.. but I can't quite figure it out
Any help would be so awesome
Upvotes: 1
Views: 258
Reputation: 1914
int fillArray(int *ptr, int n){
for(int i=0; i<n; i++){
ptr[i] = rand() % 100;
}
}
This function returns an int, but you are not returning. This results in Undefined Behaviour, which in this case may corrupt your stack, cause segfaults or weird behaviour somewhere else in the program.
int* doubleArray(int *ptr, int n){
int size = 2*n;
int * tmp = new int[size];
ptr = tmp;
delete tmp;
return ptr;
}
You are allocating tmp
using new[]
, but you are destroying it using delete
instead of delete[]
. This is also UB, and is a potential cause for a memory leak.
Do note that a memory leak in itself is not UB.
I did notice those two problems thanks to my compiler. Always enable warnings (with -Wall -Wextra
on gcc
/clang
) and read them carefully - they can spot some problems for you.
int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
}
As said by Joachim Pileborg and Gaurav Sehgal, you also trigger UB because you're returning a pointer to a local and using it, while it is supposed to be destroyed out of the scope.
Are you really getting a memory leak?
The fact that some of the values are the same tells me that I am not correctly clearing the memory, and I think it has something to do with deleting the first array I clear and then deleting the second one.. but I can't quite figure it out
This is probably not caused by a memory leak. A memory leak just leaks memory, and eats up your program's available memory. This cannot happen - The memory is still allocated (which is exactly is what a leak is), which means it won't get allocated over again for another use. Your issue really looks like it's caused by stack corruption, which has many chances to be caused by the UBs I and others pointed out.
Other alternatives
It sounds like std::vector
may fit your needs - you gain all the advantages you get when using a STL container - Iterators, generic algorithms, etc. - and especially an abstraction of dynamic memory allocation, which will help you avoid some of the issues you encountered.
If you can use at least C++11, you may also find an use in smart pointers.
Upvotes: 0
Reputation: 7542
int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
}
In the above code you are returning a pointer to a local variable arr
.When the scope of this function ends,using ptr
is undefined behavior.
int* doubleArray(int *ptr, int n){
int size = 2*n;
int * tmp = new int[size];
ptr = tmp;
delete tmp;
return ptr;
}
Here you delete the memory pointed by tmp
.Now using ptr
which points to deleted memory is undefined behavior even inside the same function.
Solution: Dynamically allocate memory inside functions
int *arr =new int[number_of_elements_required];
return arr;
Upvotes: 5
Reputation: 409166
Lets take a closer look at your initArray
function:
int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
}
Here you declare the local variable arr
. Then you return a pointer to that array. When the function returns the array will go out of scope, leaving you with a stray pointer, leading to undefined behavior.
You need to either create the array in the main
function, or create the array dynamically in the initFunction
.
The best solution though, IMO, is to not use arrays or dynamic memory allocations at all, but a std::vector
.
Upvotes: 3