How do I set a pointer to Null at run-time (C++) - c++

Right now I have a pointer set to a row in my 2D array. I want that pointer to stop pointing to that row, but I will be using the pointer later for something else. I just want to know how to unset the pointer after it is initialized and has pointed to a row.
double* tempRow;
tempRow = (double*) malloc(size * sizeof(double));
...
tempRow = NULL;
doesn't unlink the tempRow variable from the array row. Why not?
I wonder if I should be using C then instead. Will there be overhead when using a vector?

While you have written will set tempRow to NULL, it wont release the memory you have allocated. For that you need
free(tempRow);
tempRow = NULL;
However if you're using C++ as the tags suggest, you'd be better off using C++ new/delete
double* tempRow;
tempRow = new double[size];
...
delete [] tempRow;
tempRow = NULL;
you can even use the STL to handle your memory allocation for you.
std::vector<double> tempRow(size);
// You can access the data, in a similar way to an array
tempRow[5] = tempRow[4]+tempRow[3];
// If you really need to access the underlying pointer, (To pass to another
// function for example) you can do this. Note that the pointer will be valid
// until the vector is destroyed or modified in certain ways that can cause the
// vector to reallocate its memory. So you can't use this to pass data to a
// function that destroys or takes ownership of the passed in pointer.
fn_requiring_pointer( &temp[0] );
// The memory used in tempRow will get cleaned up automatically when the
// object goes out of scope
//
// If I really need to free up the memory used in it early I can use a swap
// hack. (iirc tempRow.clear() isn't guaranteed to release the memory)
std::vector<double>().swap(tempRow); // Unneeded in most cases.
Also trying to reuse the tempRow pointer for something unrelated is probably not necessary. Just create a new pointer with a different name. Reusing a variable form multiple different unrelated purposes can make code very hard to understand later.

I'm new at C++ as well, but a while ago, someone told me that using std::vector is a much safer approach to handling arrays of data.
Automatic re-allocation when adding more elements.
Iterators for use with stuff from #include <algorithm>.
Bounds-protection with .at(index) element access.
No messy pointer-tracking required.
C-array style access with operator[].
RAII.
You would declare a vector like this:
std::vector<double> tempRow(size);
tempRow[0] = 3.00;
tempRow[1] = 1.00;
// no need to use delete[] or free(), it will destruct itself
// and relinquish its resources automatically.

The example you've shown should work.Also if you've not freed the memory before making temRow NULL, you are leaking memory.
double* tempRow;
tempRow = (double*) malloc(size * sizeof(double));
...
free(tempRow); // free the memory.
tempRow = NULL; // reset the pointer.
...
tempRow = &some_other_double_var; // reuse the pointer.

Doesn't seem to work?
That's the worst complaint and a solution providers's nightmare.
Do you mean you get a compilation error?
If yes, did you include <cstdio>? and using namespace std;

Doesn't work in what way? The normal way to "unset" a pointer in C++ is with:
tempRow = 0;
but what you have should be fine, assuming you've included the correct headers or otherwise have the correct definition for NULL.
As an aside, you should first call free() on that memory before losing the pointer, otherwise you'l have a memory leak (and this is assuming you have a good reason to use C-style malloc/free instead of the more kosher C++ new/delete).

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.

Delete a vector without deleting the array

I'm trying to populate a vector of doubles in C++ and pass the associated array to Fortran. But I'm having trouble freeing the rest of the memory associated with the vector. I'd like to avoid copying. Here's what I have:
std::vector<double> *vec = new std::vector<double>();
(*vec).push_back(1.0);
(*vec).push_back(2.0);
*arr = (*vec).data(); //arr goes to Fortran
How do I delete vec while keeping arr intact? Is there a way to nullify the pointer to arr in vec so that I can then delete vec?
Update
I see that I didn't give enough information here. A couple things:
I'm actually calling a C++ function in Fortran using iso_c_binding
I don't know how large the vec needs to be. The vector class looks good for this situation
I might try Guillaume's suggestion eventually, but for now, I'm passing vec to the Fortran and calling another C++ function to delete it once I'm done with the data
You need to rethink your program design.
Somehow, somewhere, you need to keep an array alive while Fortran is using it. So whatever context you're using to access Fortran should probably be responsible for ownership of this array.
class fortran_context {
/*Blah blah blah whatever API you're using to access Fortran*/
void * arr;
std::vector<double> vec; //Don't allocate this as a pointer; makes no sense!
public:
fortran_context() {
arr = //Do whatever is necessary to setup Fortran stuff. I'm assuming your
//api has some kind of "get_array_pointer" function that you'll use.
}
~fortran_context() {
//Do the cleanup for the fortran stuff
}
//If you want to spend time figuring out a robust copy constructor, you may.
//Personally, I suspect it's better to just delete it, and make this object non-copyable.
fortran_context(fortran_context const&) = delete;
std::vector<double> & get_vector() {
return vec;
}
std::vector<double> const& get_vector() const {
return vec;
}
void assign_vector_to_array() {
*arr = vec.data();
}
void do_stuff_with_fortran() {
assign_vector_to_array();
//???
}
};
int main() {
fortran_context context;
auto & vec = context.get_vector();
vec.push_back(1.0);
vec.push_back(2.0);
context.do_stuff_with_fortran();
return 0;
} //Cleanup happens automatically due to correct implementation of ~fortran_context()
I've abstracted a lot of this because I don't know what API you're using to access Fortran, and I don't know what kind of work you're doing with this array. But this is, by far, the safest way to ensure that
The vector's allocated memory exists so long as you are doing stuff in Fortran
The memory associated with the vector will be cleaned up properly when you're done.
How do I delete vec while keeping arr intact? Is there a way to nullify the pointer to arr in vec so that I can then delete vec?
The library does not provide any built-in capability to do that. You have to do the bookkeeping work yourself.
Allocate memory for the data and copy data from the vector.
Send the data to FORTRAN.
Decide when it is safe to deallocate the data and then delete them.
// Fill up data in vec
std::vector<double> vec;
vec.push_back(1.0);
vec.push_back(2.0);
// Allocate memory for arr and copy the data from vec
double* arr = new double[vec.size()];
std::copy(vec.begin(), vec.end(), arr);
// use arr
// delete arr
delete [] arr;
What you are asking for is not possible. std::vector, being a well behaved template class will release the internals that it owns and manages when it is destroyed.
You will have to keep vector alive while you are using its contents, which makes perfect sense. Otherwise, you will have to make a copy.
Also, I don't see why you are allocating the vector on the heap, it doesn't seem needed at all.
How do I delete vec while keeping arr intact? Is there a way to nullify the pointer to arr in vec so that I can then delete vec?
You don't.
I think you misuse or misunderstood what vector is for. It is not meant to expose memory management of the underlying array, but to represent a dynamically sized array as a regular type.
If you need to explicitly manage memory, I'd suggest you to use std::unique_ptr<T[]>. Since unique pointers offers a way to manage memory and to release it's resource without deleting it, I think it's a good candidate to meet your needs.
auto arr = std::make_unique<double[]>(2);
arr[0] = 1.;
arr[1] = 2.;
auto data = arr.release();
// You have to manage `data` memory manually,
// since the unique pointer released it's resource.
// arr is null here
// data is a pointer to an array, must be deleted manually later.
delete[] data;

Remove one dynamic object from a dynamic array

I have a dynamic array (For this example, SIZE = 2):
polyTerm** polyn = new polyTerm* [SIZE];
I then add a few new ponlyTerm object to the array:
polyn[0] = new polyTerm(5.0,1);
polyn[1] = new polyTerm(2.0,1);
Now I want to remove the object from slot 0 and make the pointer null. How would I go about doing this? I currently have:
delete &polyn[0];
Then I use:
polyn[0] = NULL;
To make the pointer null.
Will this work?
EDIT:
Correction, I need to use delete polyn[0] - even so, setting that to NULL should affect the pointer, as it would still technically point to the original location of the object. Resetting it to NULL removes any errors that could pop up later.
The code you've posted is correct.
The individual object pointer, polyn[0] was created using the non-[] version of new, and so must be deleted using the non-[] version of delete -- which is what you are doing.
I'd still recommend avoiding all of this in the first place however, and using vector <unique_ptr <polyTerm> > instead. Then all you have to do is erase whatever elements you want, or clear the entire vector without having to worry about using the correct type and number of new and delete.
I'll demonstrate using a vector of smart pointers here, neatly avoiding the lack of make_unique (until C++14) by using shared_ptr instead.
// Create array (vector)
vector <shared_ptr <polyTerm>> polyn;
// Populate array
polyn.push_back (make_shared (5.0, 1));
polyn.push_back (make_shared (2,0, 1));
// Remove 0th element from array
polyn.erase (polyn.begin());

Memory Leak, source: float** binsRowPtrs = new float *[_nbins];

How do I delete this properly?
float** binsRowPtrs = new float *[_nbins];
The items are not dynamic created with new.
float** binsRowPtrs = new float *[_nbins];
for (int i = 0; i < _nbins ;i++)
{
binsRowPtrs[i] = (float*) (bins[i].row(y).data);
}
How do i delete this properly[?]
Properly? You use RAII and let something else handle the deletion for you. Depending on what you're trying to do, you may want to use:
std::vector<std::vector<float>>: an array of arrays of floats;
std::vector<float*>: an array of non-owning pointers to floats (i.e. something else handles correct allocation and deallocation);
or maybe just std::vector<float>: an array of floats.
The rule is:
Call as many delete or delete[] respectively as new or new[] you used and on the exact same addresses.
So if you just called new on binRowPtrs then you just need to call delete binRowPtrs.
However, in the part of your code which you didn't show us, If you used dynamic allocation through new for each of the array elements then you need to loop through the array and call delete on each of the element as well.
Note that ideally,
In C++ You should use dynamic allocations only when you cannot avoid them &
If et all you must, never use raw pointers, always use RAII through smart pointers to avoid the explicit memory management(you already noticed the perils of doing so in your case).
This will clear those pointers:
delete [] binsRowPtrs;
But the actual data you are storing with bins won't be touched.

How to release the memory of structures pointed by an pointer-array?

I have a pointer array defined as some_struct * t_ptr[1000] which points to a structure some_struct.And some points of the point array are evaluated.e.g
some_struct * wpaper1 = new some_struct(); //memory leaks detected in this line
wpaper1->tAnswer = useransw;
wpaper1->tKey = key;
t_ptr[100] = wpaper1;
//there're wpaper2,wpaper3....
...
delete[] t_ptr; //release the pointers
The debug message says there're memory leaks detected in the first line code.So how can I release the memory of some_struct pointed by the t_ptr array?Do I have to use a loop to detect whether a element is evaluated and then delete it?And I'm using VS2008 on Windows.Thanks.
Your delete[] t_ptr would only be correct if you've allocated t_ptr on the heap, ala:
some_struct* t_ptr = new tpr[1000];
Then, the delete[] statement releases the memory for those 1000 pointers, but does nothing about any memory that the pointers themselves may refer to. To release that, you need to first loop over the t_ptr elements, deleting them one by one:
for (i = 0; i < 1000; ++i)
delete t_ptr[i];
delete[] t_ptr;
You must ensure the pointers are set to NULL initially, though deleting a NULL pointer is a no-operation so you don't need to check in the loop above.
It's a pain isn't it? That's why a very good guideline for new C++ programmers is to use vectors and smart pointers (e.g. from boost). Those types free themselves when they go out of scope or the program exits... you don't even have to think about it.
Yes, you have to iterate over t_ptr, and delete any elements that are non-NULL (assuming you've initialized the elements to NULL before you start allocating). You should be able to identify in your code where each delete is that matches each new.