Dynamic array allocation in C++ question - c++

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.

Related

C++ array of vectors of pointers initialization

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.

can we check the size of dynamic array on runtime

I create an array of size int arr[50]; but I will insert value in it during compile time , like my solution will insert 10 values in it after performing some function (different amount of values can come) , Now in second part of my program I have to loop through the array like it should iterate <= total values of array like in int arr[50] my program save 10 values , it should iterate to it only 10 times but how I can get that there is only 10 values in that array.
arr[50]=sum;
for (int ut=0; ut<=arr[100].length();ut++)
Though i know ut<=arr[100].length() is wrong , but its just assumption , that function will work if I solve condition in this way.
Edit:
I know we can use vector , but I am just looking that type of thing using array.
Thanks for response
First of all, the array you show is not a "Dynamic Array". It's created on the stack; it's an automatic variable.
For your particular example, you could do something like this:
int arr[50];
// ... some code
int elem_count = sizeof(arr) / sizeof(arr[0]);
In that case, the sizeof(arr) part will return the total size of the array in bytes, and sizeof(arr[0]) would return the size of a single element in bytes.
However, C-style arrays come with their share of problems. I'm not saying never use them, but keep in mind that, for example, they adjust to pointers when passed as function arguments, and the sizeof solution above will give you an answer other than the one you are looking for, because it would return sizeof(int*).
As for actual dynamically allocated arrays (where all what you have is the pointer to that array), declared as follows:
int *arr = new int[50];
// ... do some stuff
delete [] arr;
then sizeof(arr) will also give you the size of an int* in bytes, which is not the size you are looking for.
So, as the comments suggested, if you are looking for a convenient random access container where you want to conveniently and cheaply keep track of the size, use a std::vector, or even a std::array.
UPDATE
To use a std::array to produce equivalent code to that in your question:
std::array<int, 50> arr;
and then use it like a normal array. Keep in mind that doing something like arr[100] will not do any bounds checking, but at least you can obtain the array's size with arr.size().

Select a random object from an array of objects

I'd like to implement a function that selects a random object from an array of objects and returns it to me. It should be something like (in C++ instead of psuedocode):
getRandomObject(objectList) {
return objectList[int(random(length of objectList))];
}
My current code looks like this, but doesn't seem to work:
//definition of random selector
object getRandomObject(Object* objectList) {
return objectList[int(ofRandom(0, sizeof(objectList)))];
};
//create a pointer for the listOfObjects
object* listOfObjects;
//create an empty object to put the randomly selected object in
object randomObject;
//later in the code, populate the array:
object* listOfObjects[] = {
new Object(),
new Object(),
new Object()
};
//select random object
randomObject = getRandomObject(listOfObjects);
But this seems to return a segmentation fault. A few problems I've noticed:
sizeof() returns the size of the pointer in getRandomObject, not the size of the array. is there a good way to get the size of the array? It might involves not using a float* pointer for the array. Is this a good use case for vectors?
I think that much of the problem lies in how I'm creating my arrays, and not so much in how I'm selecting the random object from them. I'm relatively new to C++ (coming from a Java background), so much of pointers / references / memory management in general is new to me.
thanks!
I see one definite problem and one possible one. The definite problem is that sizeof(objectList) returns the size of the objectList pointer, which will be 4 or 8 on most platforms. It does not return the number of elements in the array, objectList. Either pass in the length of the array or use std::vector or std::array.
The second possible problem relates to ofRandom. Make sure that ofRandom(a,b) returns numbers >= a, but strictly < b. If it returns values <= b, then you'll need to us ofRandom(0, objectVector.size() - 1). Typically, functions like this are written to return values strictly < b, but you should check.
C++ has an array template class that you may want to consider using. Check out the documentation here:
http://www.cplusplus.com/reference/array/array/
This type has a method, size(), that will return the length of the array.
When the sizeof operator is applied to an array, it yields the total
number of bytes in that array, not the size of the pointer represented
by the array identifier.
Quote
So you take the space alocated for your whole array and divide by the memory need just for one element: sizeof(objectList) / sizeof(*objectList).
Mr Fooz noticed issues that cause a segfault.
Other compilation issues are:
listOfObjects is declared with 2 different types: object* and object*[3] while getRandomObject expects a type Object*.
listOfObjects[] contains elements of type object* while getRandomObject reads elements of type Object and returns object.

Dynamic arrays of objects/classes in C++

I'll cut to the chase to save you all some boredom of surplus reading:
I've tried to comb the internet in search of tutorials over dynamical arrays of objects/classes where they explain how pointers are implemented here.
This in particular: TheClass **foo[10]; or something like that, I don't understand what two stars/asterisks are good for and how they are used.
And this whole thing in general.
I do know how dynamical arrays are declared,how regular pointers are used,how to make classes,how to make dynamic arrays of classes.
But all this combined got me confused.
So my questions are:
What does this do and how does it work?
Can you recommend a site where you know examples/tutorials of this can be found?
Does this have a specific name rather than "dynamic object arrays with double pointers"
or whatnot?
If no tutorial comes to mind, I'd appreciate it if you could make a very, very brief example.
Like for instance
int *something;
int somethingElse = 10;
something = &somethingElse; /*Now when you change "somethingElse","something"
will also change to the same number*/
A little super-short example and explanation like that would be greatly appreciated. =)
The simplest, more or less usefull, example using pointers to pointers would be a two dimensional array. So for example
//Create a pointer to (an array of) pointers to (an array of) ints
int** array2D;
//Create a array of pointers to (an array of) ints and assign it to the pointer
array2D = new int*[10];
//Assign each of the pointers to a new array of 10 ints
for(size_t i =0; i<10;i++) {
array2D[i] = new int[10];
}
//Now you have an 2 dimensional array of ints that can be access by
array2D[1][3] = 15;
int test = array2D[1][3];
I hope this explains a bit what pointers to pointers are and how they work.
A pointer is, well, a pointer. It points at something. Period. If you understand that much, then you should be able to understand what a pointer to a pointer is. It is just a pointer whose value is the memory address of another variable that is itself a pointer to something else. That's all. Every time you add a * to the mix, it is just another level of pointer indirection. For example:
int i;
int* p_i = &i; // p_i is a pointer to an int and points at i
int** pp_i = &p_i; // pp_i is a pointer to an int* and points at p_i
int*** ppp_i = &pp_i; // ppp_i is a pointer to an int** and points at pp_i
Now apply that concept to TheClass **foo[10]; (which is actually TheClass** foo[10]; from the compiler's perspective). It is declaring an array named foo that contains 10 TheClass** pointer-to-pointer elements. Each TheClass* might be a pointer to a specific TheClass object, or it might be a dynamic array of TheClass elements (no way to know without more context), then each TheClass** is a pointer to a particular TheClass* pointer.
Well i see you aim for the complete answer, i'll give u a brief example on that.
If you define an array of pointers to pointers, like in your "class foo**[10]" example, let's say:
int numX = 100;
int numY = 1000;
Node **some[10];
some[0] = new Node*[numX];
some[0][0] = new Node[numY];
Then what it does mean is:
You have 10 Node** in your 1st level. So you have 10 pointers to type Node**, but they aren't pointing anywhere useful yet.
This is just 10 adjacent memory locations for storing pointers. In this case it is irrelevant what they are pointing to, mainly it is just 10 fields containing space for a pointer.
Then take the first of these 10 "spaces" and assign the address of an array of 100 pointers to type Node*
some[0] = new Node*[numX]; //numX = 100
This is done and evaluated during runtime, so u can use a variable value given by user input or some application logic, to define dimensions of arrays aka memory-fields.
Now you have 1 of 10 pointers pointing to 100 pointers to type Node*, but still pointing to a black hole.
In the last step create 1000 objects of type Node and attach their addresses to the first of your 100 pointers.
some[0][0] = new Node[numY]; //numY = 1000
In the above example this means, only [0][0][0] to [0][0][999] are objects, the 1000 you created with:
This way you can build multi-dimensional arrays with the specified type. What makes the whole thing work, is that you instantiate what you need in the last dimension (3) and create pointers to uniquely index every field created from [0][0][0] to [9][99][999].
some[0][1]; // memory violation not defined
some[0][0]; // good -> points to a *Node
some[0][0][0]; // good -> actually points to Node (data)
some[1][0][0]; // memory violation not defined
As far as i know, most often you use a one-dimensional array and some tiny math, to simulate two-dimensional arrays. Like saying element [x][y] = [x+y*width];
However you want to use your memory, in the end it all boils down to some memory-adresses and their content.
TheClass** foo[10];
This line of code tells the compiler to a make an array called foo of 10 elements of type pointer to (pointer to Theclass ).
In general when you want to figure out a type that involve multiple astrisks, ampersands. Read Left to Right. so we can break out the code above to something like this:
( (Theclass) * ) * foo[10]
^ ^ ^ ^ ^
5 4 3 2 1
#1 an array of 10 elements named #2 foo #3 of type pointer #4 to pointer #5 to Theclass

Is it necessary to delete elements as an array shrinks?

I'm a student writing a method that removes zeros from the end of an array of ints, in C++. The array is in a struct, and the struct also has an int that keeps track of the length of the array.
The method examines each element starting from the last, until it encounters the first non-zero element, and marks that one as the "last element" by changing the value of length. Then the method walks back up to the original "last element", deleting those elements that are not out of bounds (the zeros).
The part that deletes the ith element in the array if i is greater than the updated length of the array, looks like this:
if (i > p->length - 1) {
delete (p->elems + i); // free ith elem
That line is wrong, though. Delete takes a pointer, yes? So my feeling is that I need to recover the pointer to the array, and then add i to it so that I will have the memory location of the integer I want to delete.
Is my intuition wrong? Is the error subtle? Or, have I got the entirely wrong idea? I've begun to wonder: do I really need to free these primitives? If they were not primitives I would need to, and in that case, how would I?
have I got the entirely wrong idea?
I'm afraid so.
If you make one new[] call to allocate an array, then you must make one delete[] call to free it:
int *p = new int[10];
...
delete[] p;
If your array is in a struct, and you make one call to allocate the struct, then you must make one call to free it:
struct Foo {
int data[10];
};
Foo *foo = new Foo;
...
delete foo;
There is no way to free part of an array.
An int[10] array actually is 10 integers, in a row (that is, 40 bytes of memory on a 32 bit system, perhaps plus overhead). The integer values which are stored in the array occupy that memory - they are not themselves memory allocations, and they do not need to be freed.
All that said, if you want a variable length array:
that's what std::vector is for
#include <vector>
#include <iostream>
struct Foo {
std::vector<int> vec;
};
int main() {
Foo foo;
// no need for a separate length: the current length of the vector is
std::cout << foo.vec.size() << "\n";
// change the size of the vector to 10 (fills with 0)
foo.vec.resize(10);
// change the size of the vector to 7, discarding the last 3 elements
foo.vec.resize(7);
}
If p->elems is a pointer, then so is p->elems + i (assuming the operation is defined, i.e. i is of integral type) - and p->elems + i == &p->elems[i]
Anyhow, you most likely don't want to (and cannot) delete ints from an array of int (be it dynamically or automatically allocated). That is
int* ptr = new int[10];
delete &ptr[5]; // WRONG!
That is simply something you cannot do. However, if the struct contains the length of the array, you could consider the array "resized" after you change the length information contained by the struct - after all, there is no way to tell the size of the array a pointer points to.
If, however your array is an array of pointers to integers (int*[]) and these pointers point to dynamically allocated memory, then yes, you could delete single items and you'd do it along the lines of your code (you are showing so little code it's difficult to be exact).