Memory Allocation in Recursive C++ Calls - c++

I'm having problems allocating and deallocating my memory in a recursive C++ program. So without using an automatic memory management solution, I wonder if anyone can help me resolve the memory leak I am experiencing.
The following code essentially explains the problem (although it's a contrived example, please correct any mistakes or simplifications I've made).
A number class to hold the value of a number:
class Number {
public:
Number() { value = 1; };
Number& operator + (const Number& n1) const {
Number result = value + n1.value;
return result;
};
int value;
};
Two functions to perform the recursion:
Number& recurse(const Number& v1) {
Number* result = new Number();
Number one = Number();
*result = *result + recurse(one);
return *result;
}
int main(...) {
Number answer = Number();
answer = recurse(result);
}
As you can see the memory allocated in the recurse function is leaked, but I'm not sure where I can free up this memory from based on the nature of the recursion?

The problem is here:
Number& operator + (const Number& n1) const {
Number result = value + n1.value;
return result;
};
You're returning a local variable (result) by reference, and that's a big NO-NO. Local variables are allocated on the stack, and when the function exits, the variables are gone. Returning a reference to a local variable is returning a pointer into the stack that's now being used for something else, and that's going to cause lots of badness.
What you should instead do is return by value (just change the return type from Number& to Number). Make sure you have an appropriate copy constructor, or that the compiler's automatically generated copy constructor suits your needs. This means when operator+ returns, it makes a copy (which can often by optimized away), and since there's no pointers or references involved, you can't get a corrupted return value.
To fix your memory leak, you can use smart pointers such as boost::shared_ptr. Alternatively, ditch pointers and dynamic memory altogether, and just return your results by value from recurse().

I don't see why you're allocating the memory on the heap to begin with:
Number& recurse(const Number& v1) {
Number result;
Number one;
// I assume there is a step here to determine if the recursion should stop
result += recurse(one);
return result;
}
By allocating only on the stack you're guaranteed that the variables will be cleaned up when the function returns.
Otherwise I think you'd have to use some sort of smart pointer.

So I see three other problems in the code other than returning the address of a local variable that Adam Rosenfield pointed out.
First, your resursive function will never end. At some point in recurse(), you must check for a value that causes it to not call recurse() again and just return. That is a fundamental part of recursion. The argument passed, v1, is also not being used.
Second, the operator+() does not actually work. There is not a way to assign an int to a Number() object.
Third, in main you pass something called result which is never declared.
Forgetting those errors, I assume that you want to allocate all the objects on the heap to avoid a stack overflow, where this function will recurse many times or the actual object used is much larger than Number. In that case by allocating the return variable on the heap inside recurse() you are forcing the caller to delete the returned object. So after the calls to recurse() in recurse() and main() you would have to delete the returned value. The convention for indicating that to the caller is to return a pointer instead of a reference. So recurse() and main() would look something like this:
Number* recurse(const Number& v1) {
Number* result = new Number();
Number one;
if(v1.value >= 2) {
Number temp;
temp.value = v1.value - 1;
Number* partialResult = recurse( temp ); //capture the object to delete
*result = *partialResult + one;
delete partialResult; //delete the object
}
return result;
}
int main() {
Number result;
result.value = 15;
Number *answer;
answer = recurse(result);
delete answer;
}
Note: Whatever recurse actually calculates is nonsensical. I don't know what the intentions are but it is just something that works.

Is there some reason you are dynamically allocating the memory?
Number recurse(const Number& v1) {
Number result;
Number one;
retun result + recurse(one);
}
Also I notice you are not using the value v1
But the big mistake is that the recursion has NO escape clause.
This is in effect an infinite recursion that will basically run out of memory.

Smart pointers are your friend. Do a quick read-up on auto_ptr at the very least.
Also, read Adam Rosenfield's comment on your other problem (returning a reference to a value that doesn't exist anymore).

Related

I want a function that changes the 2 numbers of an array quicksort

im working on a small programm which is using a quicksort algorithm.
Unfortunaly my swap function is not working.
I just wanna swap array[i] with array[j] but it says a and b are not declared.
void swap(int data[a], data[b]) {
int temp = data[a];
data[a] = data[b];
data[b] = temp;
return data[a], data[b];
}
There are a couple of problems in your code...
First, you want to swap the values of two integers (in an array), hence the function is working on ints. Further you want to modify the parameters, hence you should use references (no pointers, because passing a null pointer makes no sense for a swap).
Next, you have a return statement in a function that is declared to return nothing (void return type). Also, this
return data[a], data[b];
Wrong data types and function declared as void aside, is not doing what you expect. The comma operator evalutes both operands and the result is the operand on the right side. Anyhow this doesnt really matter here, because you don't have to return anything (instead the parameters are modified).
Fixing those we have:
void swap(int& a,int& b) {
int temp = a;
a = b;
b = temp;
}
However, you really should not write this code. There is std::swap in <utility>, that already does what you want.
PS: Passing c-style arrays to functions is a completely different story. You do not need to pass an array to the function to modify only two elements of it. Anyhow, you should probably use std::vector as it is much easier to work with.

What is the proper way to preallocate memory for a function return value that is called many times in a loop?

I'm trying to improve my c++ code and trying to improve my coding style.
I want to implement this function that is called multiple times in a loop.
Class C {
double alpha = 0.1;
std::valarray<double> f(std::valarray<double> const & arr) //called many times in a loop
{
return arr * alpha;
}
}
the array passed in is quite large and every time f returns it allocates a brand new array for the return value, really slowing down my code.
I've tried to implement a fix by preallocating a return value for it in the class it is a member of as soon as the size of the arrays are known during execution;
Class C {
double alpha = 0.1;
std::valarray<double> f_retval;
void f(std::valarray<double> const & arr) //called many times in a loop
{
f_retval = arr * alpha;
}
void allocateMembers(int Nx) //known size of the arrays used in the class
{
f_retval = std::valarray<double>(Nx);
}
}
But there must be a better way to do this. Any suggestions?
You could return by passing by non-const reference to preallocate outside of the member function.
Class C {
double alpha = 0.1;
void f(std::valarray<double> const & arr, std::valarray<double>& result) //called many times in a loop
{
result = arr * alpha;
}
}
The caller would then need to create their own preallocated result variable, but then they could reuse that variable during repeated calls to f.
std::valarray<double> f_retval = std::valarray<double>(Nx);
while (/*some condition*/) {
myC.f(toModify, f_retval);
// do something with f_retval
}
The advantages that this has over the solution that you suggested include:
the return-by-reference is more obvious to the user of the member function
the member function's functionality is more contained (it doesn't require two methods to execute), which also avoids bugs caused by improper usage
the class itself is less complex
The only potential drawback I can see with return-by-reference is that calling this method requires an extra variable declaration.
The first step to speeding this up is eliminating the memory allocations for every call to f. This requires having a valarray variable that can be reused. This can either be a member of class C or passed in as a reference parameter.
However, because the valarray multiplication operator will always allocate a new valarray, there will still be a memory allocation for each call. If performance is critical you need to roll your own multiplication loop to store the result into the reusable array (possibly resizing it to the correct size, which is essential for the first call).
In addition to not allocating new memory, this can possibly provide extra benefits from cache usage, since the memory is reused and will likely already be in the CPU data cache.

How can I make my dynamic array or vector operate at a similar speed to a standard array? C++

I'm still quite inexperienced in C++ and i'm trying to write sum code to add numbers precisely. This is a dll plugin for some finite difference software and the code is called several million times during a run. I want to write a function where any number of arguments can be passed in and the sum will be returned. My code looks like:
#include <cstdarg>
double SumFunction(int numArgs, ...){ // this allows me to pass any number
// of arguments to my function.
va_list args;
va_start(args,numArgs); //necessary prerequisites for using cstdarg
double myarray[10];
for (int i = 0; i < numArgs; i++) {
myarray[i] = va_arg(args,double);
} // I imagine this is sloppy code; however i cannot create
// myarray{numArgs] because numArgs is not a const int.
sum(myarray); // The actual method of addition is not relevant here, but
//for more complicated methods, I need to put the summation
// terms in a list.
vector<double> vec(numArgs); // instead, place all values in a vector
for (int i = 0; i < numArgs; i++) {
vec.at(i) = va_arg(args,double);
}
sum(vec); //This would be passed by reference, of course. The function sum
// doesn't actually exist, it would all be contained within the
// current function. This is method is twice as slow as placing
//all the values in the static array.
double *vec;
vec = new double[numArgs];
for (int i = 0; i < (numArgs); i++) {
vec[i] = va_arg(args,double);
}
sum(vec); // Again half of the speed of using a standard array and
// increasing in magnitude for every extra dynamic array!
delete[] vec;
va_end(args);
}
So the problem I have is that using an oversized static array is sloppy programming, but using either a vector or a dynamic array slows the program down considerably. So I really don't know what to do. Can anyone help, please?
One way to speed the code up (at the cost of making it more complicated) is to reuse a dynamic array or vector between calls, then you will avoid incurring the overhead of memory allocation and deallocation each time you call the function.
For example declare these variables outside your function either as global variables or as member variables inside some class. I'll just make them globals for ease of explanation:
double* sumArray = NULL;
int sumArraySize = 0;
In your SumFunction, check if the array exists and if not allocate it, and resize if necessary:
double SumFunction(int numArgs, ...){ // this allows me to pass any number
// of arguments to my function.
va_list args;
va_start(args,numArgs); //necessary prerequisites for using cstdarg
// if the array has already been allocated, check if it is large enough and delete if not:
if((sumArray != NULL) && (numArgs > sumArraySize))
{
delete[] sumArray;
sumArray = NULL;
}
// allocate the array, but only if necessary:
if(sumArray == NULL)
{
sumArray = new double[numArgs];
sumArraySize = numArgs;
}
double *vec = sumArray; // set to your array, reusable between calls
for (int i = 0; i < (numArgs); i++) {
vec[i] = va_arg(args,double);
}
sum(vec, numArgs); // you will need to pass the array size
va_end(args);
// note no array deallocation
}
The catch is that you need to remember to deallocate the array at some point by calling a function similar to this (like I said, you pay for speed with extra complexity):
void freeSumArray()
{
if(sumArray != NULL)
{
delete[] sumArray;
sumArray = NULL;
sumArraySize = 0;
}
}
You can take a similar (and simpler/cleaner) approach with a vector, allocate it the first time if it doesn't already exist, or call resize() on it with numArgs if it does.
When using a std::vector the optimizer must consider that relocation is possible and this introduces an extra indirection.
In other words the code for
v[index] += value;
where v is for example a std::vector<int> is expanded to
int *p = v._begin + index;
*p += value;
i.e. from vector you need first to get the field _begin (that contains where the content starts in memory), then apply the index, and then dereference to get the value and mutate it.
If the code performing the computation on the elements of the vector in a loop calls any unknown non-inlined code, the optimizer is forced to assume that unknown code may mutate the _begin field of the vector and this will require doing the two-steps indirection for each element.
(NOTE: that the vector is passed with a cost std::vector<T>& reference is totally irrelevant: a const reference doesn't mean that the vector is const but simply puts a limitation on what operations are permitted using that reference; external code could have a non-const reference to access the vector and constness can also be legally casted away... constness of references is basically ignored by the optimizer).
One way to remove this extra lookup (if you know that the vector is not being resized during the computation) is to cache this address in a local and use that instead of the vector operator [] to access the element:
int *p = &v[0];
for (int i=0,n=v.size(); i<n; i++) {
/// use p[i] instead of v[i]
}
This will generate code that is almost as efficient as a static array because, given that the address of p is not published, nothing in the body of the loop can change it and the value p can be assumed constant (something that cannot be done for v._begin as the optimizer cannot know if someone else knows the address of _begin).
I'm saying "almost" because a static array only requires indexing, while using a dynamically allocated area requires "base + indexing" access; most CPUs however provide this kind of memory access at no extra cost. Moreover if you're processing elements in sequence the indexing addressing becomes just a sequential memory access but only if you can assume the start address constant (i.e. not in the case of std::vector<T>::operator[]).
Assuming that the "max storage ever needed" is in the order of 10-50, I'd say using a local array is perfectly fine.
Using vector<T> will use 3 * sizeof(*T) (at least) to track the contents of the vector. So if we compare that to an array of double arr[10];, then that's 7 elements more on the stack of equal size (or 8.5 in 32-bit build). But you also need a call to new, which takes a size argument. So that takes up AT LEAST one, more likely 2-3 elements of stackspace, and the implementation of new is quite possibly not straightforward, so further calls are needed, which take up further stack-space.
If you "don't know" the number of elements, and need to cope with quite large numbers of elements, then using a hybrid solution, where you have a small stack-based local array, and if numargs > small_size use vector, and then pass vec.data() to the function sum.

I cant get my destructor to work in my code

Like i said in the title i cant get the destructor to work. The reason being is that in this program i am required to use a int* array with negative indices: I keep getting this error at random times while running also: Microsoft C++ exception: std::bad_alloc at memory location 0x009DF130.
heres the code that i believe involves the error:
private: int* run;
IntArray::IntArray(int a, int b)
{
int c = b-a;
run = new int [c] + a; //This is how i give it a negative indicie
h = b;
l = a;
}
IntArray::~IntArray()
{
delete[]run;
}
string IntArray::setName(string sp)
{
s = sp;
return s;
}
void runSim() {
IntArray b(-4, 6);
for (int i = b.low(); i <= b.high(); i++)
// low is the lowes bound high is the highest
b[i] = i * 10;
b.setName("b"); //this is where it breaks and gives me that error
wait();
}
The only right way to do this is to define a custom operator[] on your class. The code you have has numerous errors:
You access both low and high, that's high-low+1 elements. But you only allocate high-low.
If p=new int[high-low+1], then run=p+low; and run[low] means *(p + low + low). This is the proximate cause of your crash -- you wrote way outside the array, trashing internal metadata, which made dynamic allocation fail for the next user, your string's assignment operator.
You should have subtracted low when computing run, so that run[low] would give p[0], the first allocated element. But this might calculate a pointer outside the array (when low is positive), which is undefined behavior.
You pass a pointer to delete[] that didn't come from array new. You need to pass p, not run, to delete[].
You have no attempt at exception safety. Management of dynamic memory in C++ is an advanced topic, and the evidence shows that you are not ready to do it yet. So use an existing smart pointer to manage your memory.
Here's a better version:
#include <memory>
template<typename T>
class ArbBoundArray
{
int low;
std::unique_ptr<T[]> base;
public:
ArbBoundArray(int l, int h) : low(l), base(new T[h-l+1]) {}
T& operator[](int o) { return base[o-low]; }
const T& operator[](int o) const { return base[o-low]; }
};
That's it. Less code, works for any type not just int, and exception-safe.
You can add your special needs like a name or whatever on top of that basic concept.
Your have a simple errors:
Do not pass a value to delete [] you didn't get from new [] (or already passed once).
You need to undo your pointer-arithmetic to get the right pointer.
Also, be aware that if you create a pointer which points outside the array using pointer-arithmetic, you have Undefined Behavior.
If that's not your actual code, beware of trying to allocate less than 1 element.
Since you add a (aka l) to run when you new it, you must subtract when you delete it:
delete[] (run - l);
Not trying to be mean, but this is pretty bad code.
First of all, if b - a returns a number less than 0 you will probably get an std::bad_alloc and if a > c you will be stepping into undefined behaviour [scary] territory and will probably get a segfault if you try to use the pointer.
Seeing as though you try to delete[] the pointer that points to new int[c] + a you almost certainly will get a segfault.
You need to do run -= a before trying to delete[] it, the implementation will either store information about any new or malloc in the space before the pointer that you get given so that when you delete or free the memory it just has to run behind the pointer and get any information it needs or store the info in a hidden array somewhere that is indexed by the numerical representation of the pointer. But probably the first. Either way, you're screwed doing what you're doing.

Return 2D vector using pointer in C++

all
I am using a 2D vector to return my results from a function to main. The 2D vector is very large, and the function is excuted 10K+ times, thus I have to return it using pointer to speed it up.
Here is my code:
vector<vector<double>>* someFunction()
{
vector<vector<double>> results;
//do something...
return &results;
}
and in main:
int main()
{
// do something
////////// EDIT: vec is a pointer, I missed * at first place
vector<vector<double>>* vec = someFunction(); // vec is empty!
cout<<vec.size(); // size = 0
return;
}
When I check the value and size of vec in main, it turned out that vec is size 0.
May I know what am I wrong?
Many thanks in advance.
Regards
Long
You are returning a pointer to a local variable. This variable ceases to exist when the function scope is exited, leaving you with a dangling pointer. This is undefined behaviour.
Just return a value:
vector<vector<double>> someFunction()
{
vector<vector<double>> results;
//do something...
return results;
}
If you are worried about expensive copies involved in returning by value, bear in mind that it is extremely likely that these will be elided via return value optimization (RVO), specifically named return value optimization (NRVO). Even if this doesn't happen (it is optional, so implementations can decide not to do it), in C++11 move semantics would kick in. Moving an std::vector<double> is extremely cheap.
you return a pointer to vector. remove the * in the method:
vector<vector<double>> someFunction()
and of course return the vector, not a pointer to it
Are you not returning a reference to a local variable here, therefore going out of scope? Make it a member of the class, assuming its in a class
Alternatively pass the reference into the function as a parameter
void someFunction(vector<vector<double>>& results)
{
results.clear();
//do something...
}
There appears already to be a popular answer, but there is a way to do exactly what your asking using dynamic memory allocation. I feel like this is worth pointing out since, although it may not be the best way to approach this particular problem, dynamic memory allocation is a very useful technique in general. The idea is that "someFunction" should create a pointer to a dynamically allocated piece of memory which will hold the vector<vector<double>>. Here is working code using smart pointers but one could instead use the traditional new and delete keywords for allocation also if c++11 is not your thing:
#include <memory>
#include <vector>
using namespace std;
shared_ptr<vector<vector<double>>> someFunction() {
vector<vector<double>> result;
//Do stuff with result
shared_ptr<vector<vector<double>>> resultPtr =
make_shared<vector<vector<double>>>(result);
return resultPtr;
}
int main() {
shared_ptr<vector<vector<double>>> ptr;
ptr = someFunction();
return 0;
}
Like I said it may not be the best way, but let it be known that returning a pointer to a local object can indeed be done correctly using dynamic memory allocation.