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());
Related
I want to allocate an array of vectors in a function. Every vector should be initiated with a size of 0. Afterwards I want to push pointers to objects T to my vectors. Finally I want have a grid with a list of references in every cell. I am stuck at the initialization of the vectors. It seems that they are not allocated ?
typedef std::vector<T*> GridCell;
GridCell* mGrid;
...
int gridSize = 5;
mGrid = new GridCell[gridSize];
mGrid[gridSize] = { GridCell() }; //runtime error here
This might be possibly duplicated to other posts, but I couldn't find one that solves this issue 100%.
mGrid = new GridCell[gridSize];
This line not only allocates an array, but it default constructs all of the entries too!
mGrid[gridSize]
This is an out of bounds error; as the array has length 5, the only valid indices are 0, 1, 2, 3, 4. Trying to access an element at index 5 is undefined behavior.
vector<GridCell> mGrid(5);
// vector<GridCell> mGrid(5, GridCell()); // Same thing as the line above
This is what you should have done instead. With modern C++, it's pretty rare that you should ever have to use new; there are standard objects that serve most of the purposes people once used new for (e.g. using vector instead of dynamically an array), there are smart pointers for most of the remaining cases, and for the few cases still remaining, you're usually better served by writing your own custom class whose purpose in life is to be a wrapper around whatever you're doing with new.
I would like to be sure that this is not wrong: I initialize array with
double* lower = input->getLowerBox();
where function getLowerBox() returns some double*. is it correct? Or shold I initialize this way::
double* lower = new double[nbP];
for (int i=0;i<nbP;i++)
lower[i]=input->getLowerBox()[i];
or to avoid multiple calls to getLowerBox,
double* lower = new double[nbP];
double* tmp = input->getLowerBox();
for (int i=0;i<nbP;i++)
lower[i]=tmp[i];
delete[] tmp;
Two steps recipe:
Change Input::getLowerBox() to return std::vector<double> const&
Use a copy if you want to modify the returned value, and the const reference instead
Well, it depends on what you want to do. Do you need a new array or not.
Your first snippet doesn't create a new array, so memory management is more important.
For example:
double* lower = input->getLowerBox();
delete[] lower;
would possibly render input->getLowerBox() invalid. Or something like:
double* lower = NULL;
{
Class input;
lower = input->getLowerBox();
}
//...
would make lower a dangling pointer, if input clears the contents of the array in the destructor.
The last two snippets create new arrays. It is safer IMO, but also uses extra memory.
Both are correct, depending on what you want to do. Whichever you choose, make sure to document it fully.
The first way is fine. You're going to return a pointer to a double, which I'm assuming is related to an array (If not, then please correct me). By doing that, you're pointing to the first element of that array and then you can just index lower or use pointer arithmetic to access the other elements.
EDIT: Could you post the definition of getLowerBox() so it's more clear to what you're trying to do?
Do you have the ability to change getLowerBox() ? If so, I would change it so it returns a vector.
Depending on the implementation, it might return you a pointer which you can own or a pointer to an internal static (bad but possible) so you need to know what it's doing and act accordingly by retaining the pointer or taking a copy of the array respectively.
If you don't have control over getLowerBox() and you know the size of the array it returns, it would be a reasonable idea copy it to a vector
double* lower = input->getLowerBox();
vector<double> lowerV(lower, lower + N );
(where N is the size of the array - BTW this is just from memory, I haven't compiled it.)
I would definitely go with the first one for multiple reasons. It's cleaner, it avoids unnecessary calls / variable creation, etc. Just make sure that input's a pointer if you're using "->"; otherwise use ".".
I have a dynamically allocated array :
myRectangle lastRectanglesArray = new myRectangle[lastMaxLabel];
I would like to loop through all elements in this array and remove these that will meet my condition (e.g. too big rectangle).
I have been thinking that I can loop through this array and get the number of elements that would satisfy my condition and then allocate a new array. But how can I 'transfer' these 'wanted' elements into my new array ?
Just for the record: I cannot use STL containers.
myRectangle * lastRectanglesArray = new myRectangle[lastMaxLabel];
// initialize the entries in the lastRectanglesArray
// create a temporary array which contains info about each individual
// entry. namely, it only holds info about whether the entry should
// be kept, or deleted.
// we also use the 'entries' value, which is the number of entries
// in the new array
bool * entriesToKeep = new bool[lastMaxLabel];
int entries = 0;
// check each entry, and mark whether it should be kept or deleted
for (int i = 0; i != lastMaxLabel; ++i) {
// check whether the entry should be kept or deleted...
// here, i just put a function with signature like:
// bool shouldKeepRectangle(const myRectangle &);
entriesToKeep[i] = shouldKeepRectangle(lastRectanglesArray[i]);
if (entriesToKeep[i]) ++entries;
}
// create a new array that will contain the entries that should be kept
myRectangle * rectanglesArray = new myRectangle[entries];
// assign the entries in the new array
for (int i = 0, j = 0; i != lastMaxLabel && j != entries; ++i) {
if (entriesToKeep[i])
rectanglesArray[j++] = lastRectanglesArray[i];
}
// free the memory held by the temp array
delete [] entriesToKeep;
// if the old array is not needed anymore, delete it
delete [] lastRectanglesArray;
// and here you have rectanglesArray, a brand new array that contains
// only the elements that you need.
Just move the next array location over the one that needs to be deleted, and shift everything over til the end of the array.
Yours look like the perfect case for using a Linked List. You would however have to do away with the new myRectangle[lastMaxLabel] part as you would have to implement it as pert of your Insert() function.
This way you would not require to transfer the wanted elements into a new array, but just delete the unwanted element.
Any more light on your use-case would help us to think of better alternatives.
I agree with Michael Chinen - use std::vector instead. You'll avoid lots of other potential problems this way. If you really want to use dynamic arrays, see this question: Remove an array element and shift the remaining ones
if you have a big amount of data in array that will be a problem for shifting using loop
maybe you should build your own array management class (find,add,deleteAt,etc).
my suggestion use link list node method.. it will be faster rather then you use loop for shifting.
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).
I have a struct of type Duplicate
I have a variable of type int called stringSize, it has a value of 5
I am creating a dynamic array:
Duplicate *duplicates;
duplicates = new Duplicate[stringSize - 1];
Later I delete[] duplicates;
I'm getting one member in that array only? I've verified that stringSize - 1 = 4 with a debug walk through. What can I do to get the 4 members I need?
Any help appreciated,
Thanks // :)
Duplicate *duplicates;
duplicates = new Duplicate[stringSize - 1];
Indeed gives you duplicates[0-3] (Assuming stringSize - 1 is 4, like you say). How are you determining you're getting less?
I suspect you may be doing something like: sizeof(duplicates) / sizeof(duplicates[0]), and on an off-change getting one. The above code only works for statically allocated arrays, where sizeof(duplicates) would match the size of the array, in bytes. In your case, it'll simply return the size of a pointer on your system. (duplicates is a Duplicate*)
And mandatory: Use std::vector if this is "real" code.
Your debugger is doing the best it can. As far is it's concerned, you've merely got a pointer to some data. Consider:
Duplicate foo;
Duplicate *duplicates_A;
duplicates_A = &foo; // points to one Duplicate
Duplicate *duplicates_B;
duplicates_B = new Duplicate[4]; // points to memory containing 4 Duplicate's
bar(duplicates_A);
bar(duplicates_B);
void bar(Duplicate* p)
{
// is p a pointer to one value, or is it an array?
// we can't tell, and this is the same boat your debugger is in
}
How should the debugger, just given a pointer, know if it's pointing to an array or just one value? It cannot, safely. (It would have to determine, somehow, if the pointer was to an array, and the size of that array.)
You can't use sizeof to determine the size of a dynamic array. In fact, there isn't a standard API to determine the size of a dynamic array.
Use std::vector if you need to access the size.
If you use a debugger to view the elements you get, the problem may be that the type of your variable is Duplicate* which is just a pointer (which in C happens to also be an array but the type is just a pointer to one instance of Duplicate.