Problems Expanding an Array in C++ - c++

I'm writing a simulation for class, and part of it involves the reproduction of organisms. My organisms are kept in an array, and I need to increase the size of the array when they reproduce. Because I have multiple classes for multiple organisms, I used a template:
template <class orgType>
void expandarray(orgType* oldarray, int& numitems, int reproductioncount)
{
orgType *newarray = new orgType[numitems+reproductioncount];
for (int i=0; i<numitems; i++) {
newarray[i] = oldarray[i];
}
numitems += reproductioncount;
delete[] oldarray;
oldarray = newarray;
newarray = NULL;
}
However, this template seems to be somehow corrupting my data. I can run the program fine without reproduction (commenting out the calls to expandarray), but calling this function causes my program to crash. The program does not crash DURING the expandarray function, but crashes on access violation later on.
I've written functions to expand an array hundreds of times, and I have no idea what I screwed up this time. Is there something blatantly wrong in my function? Does it look right to you?
EDIT: Thanks for everyone's help. I can't believe I missed something so obvious. In response to using std::vector: we haven't discussed it in class yet, and as silly as it seems, I need to write code using the methods we've been taught.

You need to pass oldarray as a reference: orgType *& oldarray. The way it's currently written, the function will delete the caller's array but will not give it the newly allocated one, causing the crash.
Better yet, use std::vector instead of reimplementing it.

The C++ standard library already has functionality written to do this.
Use the std::vector container.

Looks like you are modifying the pointer oldarray to point to the new array, but remember in the function that's just a copy and won't affect the variable you passed in. You probably need to pass a reference to a pointer if you want to do it this way.
And indeed, std::vector does this for you anyway

Related

Better way to store the address and value of a pointer, and reuse that same pointer variable without using dynamic memory allocation

Sorry if this question is already answered somewhere else, but I've been searching for a couple days and haven't been able to find exactly what I'm looking for.
I was wondering what a safer/cleaner way is to store a pointer (keep the address and value the same and store in some container) and reuse that same pointer variable.
Currently, I'm just using dynamic memory allocation and manually deleting it later on, but I was wondering if there is a better way to do this (I'll elaborate more after the code, since it may be easier to understand what I'm asking for then).
I attached some sample code below with what I'm talking about, and how I am currently doing it (please bear with me on any glaring mistakes, I'm still learning C++):
struct MyStruct{
double* arr;
MyStruct* parent_struct;
};
MyStruct* first_struct = new MyStruct;
first_struct->arr = some_array;
first_struct->parent_struct = nullptr;
std::vector<MyStruct*>* my_vector = new std::vector<MyStruct*>();
my_vector->push_back(first_struct);
double* temp_array;
MyStruct* temp_struct;
MyStruct* previous_struct;
for (i=0; i<num_iterations; i++){
temp_array = new double[sizeofarray];
assign_some_values(temp_array);
assign_struct_some_values(previous_struct);
if (some_condition(temp_array)){
temp_struct = new MyStruct;
temp_struct->arr = temp_array;
temp_struct->parent_struct = previous_struct;
my_vector->push_back(temp_struct);
} else{
delete [] temp_array;
}
}
... use values in my_vector ...
for (j=0; j<my_vector.size(); j++){
delete [] (*my_vector)[j]->arr;
delete (*my_vector)[j];
}
delete my_vector;
The main thing is, what alternative to the dynamically allocated arrays/structures can I use?
Please keep in mind that I would like to try to keep the address and values the same once they are added to my_vector, if at all possible (due to some requirements with the code I'm using). I feel like there is a much better way to do this without dynamic memory allocation, or so many pointers (like using smart pointers, std::array, etc), but I haven't been able to properly get any of the other methods to work.
When I try using smart pointers, I can't seem to get the custom deleter to work properly for the structures.
And when using a container (like std::vector) for the arr variables instead of double*, they keep getting deallocated (or I'm accidentally changing the address/values somehow) before the for loop is finished.

Memory errors in array resize

So I'm trying to make a template class for a heap. I'm trying not to use any of the STL classes (professor's rules and whatnot) so rather than use a vector I use a dynamically allocated array. However, when I run the program and input enough data into the heap for it to trigger the resizing function, it springs a bunch of memory errors. Some gdb work narrowed it down to this function:
template <class T>
T* Heap<T>::resize()
{
T* temp; //temp variable for storage
heap_capacity *= 2; //double capacity
temp = new T[heap_capacity]; //create new enlarged array
for (int i = 0; i < heap_size; ++i)
{
temp[i] = heap_arr[i]; //copy elements from previous array to current
}
delete [] heap_arr; //delete old array
return temp; //return new array
}
Pretty standard stuff, tbh. It requires whatever T is to have an assignment operator, but I was testing it using plain old integers. This isn't the first time I've written this code, but it is the first time I've written it for a template. Does the problem lie in this function, or is it somewhere else?
Edit: I played around with the code a little bit more in gdb. Turns out the program errors out right after I allocate memory for temp. This is strange, because I do the same thing for the original heap_array in the constructor. I'll be poking around a bit more, but is my syntax wrong for the "new" statement? heap_capacity is valid, btw, so that's not the problem...
It looks like you need to set heap_arr to point to the new expanded memory. It would certainly make sense for the resize method to take care of this:
delete [] heap_arr;
heap_arr = temp;
return heap_arr;
You also need to be sure that the heap_size is less than heap_capacity.
Well, I've figured out why I was getting the error. Turns out my check to see if the size of the heap was equal to the capacity forgot a crucial part: the extra 0 at the top of the array. The heap is 1-based (as opposed to 0-based) so the fix was simple: change the heap_size == heap_capacity statement to heap_size == heap_capacity-1... an important distinction. Thank you all for your help.

How to demonstrate memory error using arrays in C++

I'm trying to think of a method demonstrating a kind of memory error using Arrays and C++, that is hard to detect. The purpose is to motivate the usage of STL vector<> in combination with iterators.
Edit: The accepted answer is the answer i used to explain the advantages / disadvantages. I also used: this
Improperly pairing new/delete and new[]/delete[].
For example, using:
int *array = new int[5];
delete array;
instead of:
int *array = new int[5];
delete [] array;
And while the c++ standard doesn't allow for it, some compilers support stack allocating an array:
int stack_allocated_buffer[size_at_runtime];
This could be the unintended side effect of scoping rules (e.g constant shadowed by a member variable)... and it works until someone passes 'size_at_runtime' too large and blows out the stack. Then lame errors ensue.
A memory leak? IMO, vector in combination with iterators doesn't particularly protect you from errors, such as going out of bounds or generally using an invalidated iterator (unless you have VC++ with iterator debugging); rather it is convenient because it implements a dynamically resizable array for you and takes care of memory management (NB! helps make your code more exception-safe).
void foo(const char* zzz)
{
int* arr = new int[size];
std::string s = zzz;
//...
delete[] arr;
}
Above can leak if an exception occurs (e.g when creating the string). Not with a vector.
Vector also makes it easier to reason about code because of its value semantics.
int* arr = new int[size];
int* second_ref = arr;
//...
delete [] arr;
arr = 0; //play it safe :)
//...
second_ref[x] = y;
//...
delete [] second_ref;
But perhaps a vector doesn't automatically satisfy 100% of dynamic array use cases. (For example, there's also boost::shared_array and the to-be std::unique_ptr<T[]>)
I think the utility of std::vector really shows when you need dynamic arrays.
Make one example using std::vector. Then one example using an array to realloc. I think it speaks for itself.
One obvious:
for (i = 0; i < NUMBER_OF_ELEMENTS; ++i)
destination_array[i] = whatever(i);
versus
for (i = 0; i < NUMBER_OF_ELEMENTS; ++i)
destination_vector.push_back(whatever(i));
pointing out that you know the second works, but whether the first works depends on how destination_array was defined.
void Fn()
{
int *p = new int[256];
if ( p != NULL )
{
if ( !InitIntArray( p, 256 ) )
{
// Log error
return;
}
delete[] p;
}
}
You wouldn't BELIEVE how often I see that. A classic example of where any form of RAII is useful ...
I would think the basic simplicity of using vectors instead of dynamic arrays is already convincing.
You don't have to remember to delete your memory...which is not so simple since attempts to delete it might be bypassed by exceptions and whatnot.
If you want to do dynamic arrays yourself, the safest way to do it in C++ is to wrap them in a class and use RAII. But vectors do that for you. That's kind of the point, actually.
Resizing is done for you.
If you need to support arbitrary types, you don't have to do any extra work.
A lot of algorithms are provided which are designed to handle containers, both included and by other users.
You can still use functions that need arrays by passing the vector's underlying array if necessary; The memory is guaranteed to be contiguous by the standard, except with vector<bool> (google says as of 2003, see 23.2.4./1 of the spec).
Using an array yourself is probably bad practice in general, since you will be re-inventing the wheel...and your implementation will almost definitely be much worse than the existing one...and harder for other people to use, since they know about vector but not your weird thing.
With a dynamic array, you need to keep track of the size yourself, grow it when you want to insert new elements, delete it when it is no longer needed...this is extra work.
Oh, and a warning: vector<bool> is a dirty rotten hack and a classic example of premature optimization.
Why don't you motivate it based on the algorithms that the STL provides?
In raw array, operator[] (if I may call so) is susceptible to index-out-of-bound problem. With vector it is not (There is at least a run time exception).
Sorry, I did not read the question carefully enough. index-out-of-bound is a problem, but not a memory error.

Dedicated function for memory allocation causes memory leak?

Hy all,
I believe that the following piece of code is generating memory leak?
/* External function to dynamically allocate a vector */
template <class T>
T *dvector(int n){
T *v;
v = (T *)malloc(n*sizeof(T));
return v;
}
/* Function that calls DVECTOR and, after computation, frees it */
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
int e,f,n,p;
double *Left_Conserved;
Left_Conserved = dvector<double>(NumberOfProperties);
//do stuff with Left_Conserved
//
free(Left_Conserved);
return;
}
I thought that, by passing the pointer to DVECTOR, it would allocate it and return the correct address, so that free(Left_Conserved) would successfully deallocate. However, it does not seem to be the case.
NOTE: I have also tested with new/delete replacing malloc/free without success either.
I have a similar piece of code for allocating a 2-D array. I decided to manage vectors/arrays like that because I am using them a lot, and I also would like to understand a bit deeper memory management with C++.
So, I would pretty much like to keep an external function to allocate vectors and arrays for me. What's the catch here to avoid the memory leak?
EDIT
I have been using the DVECTOR function to allocate user-defined types as well, so that is potentially a problem, I guess, since I don't have constructors being called.
Even though in the piece of code before I free the Left_Conserved vector, I also would like to otherwise allocate a vector and left it "open" to be assessed through its pointer by other functions. If using BOOST, it will automatically clean the allocation upon the end of the function, so, I won't get a "public" array with BOOST, right? I suppose that's easily fixed with NEW, but what would be the better way for a matrix?
It has just occurred me that I pass the pointer as an argument to other functions. Now, BOOST seems not to be enjoying it that much and compilation exits with errors.
So, I stand still with the need for a pointer to a vector or a matrix, that accepts user-defined types, that will be passed as an argument to other functions. The vector (or matrix) would most likely be allocated in an external function, and freed in another suitable function. (I just wouldn't like to be copying the loop and new stuff for allocating the matrix everywhere in the code!)
Here is what I'd like to do:
template <class T>
T **dmatrix(int m, int n){
T **A;
A = (T **)malloc(m*sizeof(T *));
A[0] = (T *)malloc(m*n*sizeof(T));
for(int i=1;i<m;i++){
A[i] = A[i-1]+n;
}
return A;
}
void Element::setElement(int Ptot, int Qtot){
double **MassMatrix;
MassMatrix = dmatrix<myT>(Ptot,Qtot);
FillInTheMatrix(MassMatrix);
return;
}
There is no memory leak there, but you should use new/delete[] instead of malloc/free. Especially since your function is templated.
If you ever want to to use a type which has a non-trivial constructor, your malloc based function is broken since it doesn't call any constructors.
I'd replace "dvector" with simply doing this:
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
double *Left_Conserved = new double[NumberOfProperties];
//do stuff with Left_Conserved
//
delete[] Left_Conserved;
}
It is functionally equivalent (except it can call constructors for other types). It is simpler and requires less code. Plus every c++ programmer will instantly know what is going on since it doesn't involve an extra function.
Better yet, use smart pointers to completely avoid memory leaks:
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
boost::scoped_array<double> Left_Conserved(new double[NumberOfProperties]);
//do stuff with Left_Conserved
//
}
As many smart programmers like to say "the best code is the code you don't have to write"
EDIT: Why do you believe that the code you posted leaks memory?
EDIT: I saw your comment to another post saying
At code execution command top shows
allocated memory growing
indefinitely!
This may be completely normal (or may not be) depending on your allocation pattern. Usually the way heaps work is that they often grow, but don't often shrink (this is to favor subsequent allocations). Completely symmetric allocations and frees should allow the application to stabilize at a certain amount of usage.
For example:
while(1) {
free(malloc(100));
}
shouldn't result in continuous growth because the heap is highly likely to give the same block for each malloc.
So my question to you is. Does it grow "indefinitely" or does it simply not shrink?
EDIT:
You have asked what to do about a 2D array. Personally, I would use a class to wrap the details. I'd either use a library (I believe boost has a n-dimmentional array class), or rolling your own shouldn't be too hard. Something like this may be sufficient:
http://www.codef00.com/code/matrix.h
Usage goes like this:
Matrix<int> m(2, 3);
m[1][2] = 10;
It is technically more efficient to use something like operator() for indexing a matrix wrapper class, but in this case I chose to simulate native array syntax. If efficiency is really important, it can be made as efficient as native arrays.
EDIT: another question. What platform are you developing on? If it is *nix, then I would recommend valgrind to help pinpoint your memory leak. Since the code you've provided is clearly not the problem.
I don't know of any, but I am sure that windows also has memory profiling tools.
EDIT: for a matrix if you insist on using plain old arrays, why not just allocate it as a single contiguous block and do simple math on indexing like this:
T *const p = new T[width * height];
then to access an element, just do this:
p[y * width + x] = whatever;
this way you do a delete[] on the pointer whether it is a 1D or 2D array.
There is no visible memory leak, however there is a high risk for a memory leak with code like this. Try to always wrap up resources in an object (RAII).
std::vector does exactly what you want :
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
int e,f,n,p;
std::vector<double> Left_Conserved(NumOfProperties);//create vector with "NumOfProperties" initial entries
//do stuff with Left_Conserved
//exactly same usage !
for (int i = 0; i < NumOfProperties; i++){//loop should be "for (int i = 0; i < Left_Conserved.size();i++)" .size() == NumOfProperties ! (if you didn't add or remove any elements since construction
Left_Conserved[i] = e*f + n*p*i;//made up operation
}
Left_Conserved.push_back(1.0);//vector automatically grows..no need to manually realloc
assert(Left_Conserved.size() == NumOfProperties + 1);//yay - vector knows it's size
//you don't have to care about the memory, the Left_Conserved OBJECT will clean it up (in the destructor which is automatically called when scope is left)
return;
}
EDIT: added a few example operations. You really should read about STL-containers, they are worth it !
EDIT 2 : for 2d you can use :
std::vector<std::vector<double> >
like someone suggested in the comments. but usage with 2d is a little more tricky. You should first look into the 1d-case to know what's happening (enlarging vectors etc.)
No, as long as you aren't doing anything drastic between the call to your dvector template and the free, you aren't leaking any memory. What tells you there is a memory leak?
May I ask, why you chose to create your own arrays instead of using STL containers like vector or list? That'd certainly save you a lot of trobule.
I don't see memory leak in this code.
If you write programs on c++ - use new/delete instead malloc/free.
For avoid possible memory leaks use smart pointers or stl containers.
What happens if you pass a negative value for n to dvector?
Perhaps you should consider changing your function signature to take an unsigned type as the argument:
template< typename T >
T * dvector( std::size_t n );
Also, as a matter of style, I suggest always providing your own memory release function any time you are providing a memory allocation function. As it is now, callers rely on knowledge that dvector is implemented using malloc (and that free is the appropriate release call). Something like this:
template< typename T >
void dvector_free( T * p ) { free( p ); }
As others have suggested, doing this as an RAII class would be more robust. And finally, as others have also suggested, there are plenty of existing, time-tested libraries to do this so you may not need to roll your own at all.
So, some important concepts discussed here helped me to solve the memory leaking out in my code. There were two main bugs:
The allocation with malloc of my user-defined types was buggy. However, when I changed it to new, leaking got even worse, and that's because one my user-defined types had a constructor calling an external function with no parameters and no correct memory management. Since I called that function after the constructor, there was no bug in the processing itself, but only on memory allocation. So new and a correct constructor solved one of the main memory leaks.
The other leaking was related to a buggy memory-deallocation command, which I was able to isolate with Valgrind (and a bit a patience to get its output correctly). So, here's the bug (and, please, don't call me a moron!):
if (something){
//do stuff
return; //and here it is!!! =P
}
free();
return;
And that's where an RAII, as I understood, would avoid misprogramming just like that. I haven't actually changed it to a std::vector or a boost::scoped_array coding yet because it is still not clear to me if a can pass them as parameter to other functions. So, I still must be careful with delete[].
Anyway, memory leaking is gone (by now...) =D

How to handle passing runtime-sized arrays between classes in C++

Right now I have a simple class that handles the parsing of XML files into ints that are useful to me. Looks something like this:
int* DataParser::getInts(){
*objectNumbers = new int[getSize()];
for (int i=0;i<getSize();i++){
objectNumbers[i]=activeNode->GetNextChild()->GetContent();
}
return objectNumbers;
}
In the main part of the program, I receive this by doing:
int* numbers= data->getInts();
///Do things to numbers[]
delete numbers;
Everything works fine until the delete command, which crashes everything. What is the proper way of doing this?
Part of the problem is that you are not pairing new[] with delete[]. This probably isn't the root of your bug here but you should get in the habbit of doing this.
The bug is almost certainly related to the code that you left commented out. Can you add some more context there so we can see what you're doing with the numbers value?
In general, I find it's much easier to use a vector for this type of problem. It takes the memory management out of the equation and has the added benefit of storing the size with the dynamic memory.
void DataParser::getInts(std::vector<int>& objectNumbers){
for (int i=0;i<getSize();i++){
objectNumbers.push_back(activeNode->GetNextChild()->GetContent());
}
}
...
std::vector<int> numbers;
data.getInts(numbers);
You need to
delete [] numbers;
The rules is whenever you
ptr = new Type[...];
make sure you
delete [] ptr;
instead of the regular
delete ptr;
which will result in undefined behavior (thanks Neil Butterworth) and is intended for deletion of a single instance where ptr points, not an array.
The following line:
*objectNumbers = new int[getSize()];
What does it do? If you are returning objectNumbers, this is a pointer to int, and you should really be doing:
objectNumbers = new int[getSize()];
Anyway, C++ gives you collections (vector, list etc) -- I'd have used one of those instead of a plain array. As noted elsewhere it is important to match your new with a delete and a new [] with a delete [].
Passing arrays around isn't good design -- you are making the implementation public. Try to pass iterators to the begining and end of the array/collection/sequence of ints instead following the STL design.
simply use a std::vector instead;
std::vector<int> DataParser::getInts(){
std::vector<int> objectNumbers(getSize());
for (int i=0;i<getSize();i++){
objectNumbers[i]=activeNode->GetNextChild()->GetContent();
}
return objectNumbers;
}
You will quickly run into trouble and maintenance issues. Consider using std::vector, this is the proper way to do it.