Dynamic arrays of objects/classes in C++ - 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

Related

How to pass dynamic and static 2d arrays as void pointer?

for a project using Tensorflow's C API I have to pass a void pointer (void*) to a method of Tensorflow. In the examples the void* points to a 2d array, which also worked for me. However now I have array dimensions which do not allow me to use the stack, which is why I have to use a dynamic array or a vector.
I managed to create a dynamic array with the same entries like this:
float** normalizedInputs;//
normalizedInputs = new float* [noCellsPatches];
for(int i = 0; i < noCellsPatches; ++i)
{
normalizedInputs[i] = new float[no_input_sizes];
}
for(int i=0;i<noCellsPatches;i++)
{
for(int j=0;j<no_input_sizes;j++)
{
normalizedInputs[i][j]=inVals.at(no_input_sizes*i+j);
////
////
//normalizedInputs[i][j]=(inVals.at(no_input_sizes*i+j)-inputMeanValues.at(j))/inputVarValues.at(j);
}
}
The function call needing the void* looks like this:
TF_Tensor* input_value = TF_NewTensor(TF_FLOAT,in_dims_arr,2,normalizedInputs,num_bytes_in,&Deallocator, 0);
In argument 4 you see the "normalizedInputs" array. When I run my program now, the calculated results are totally wrong. When I go back to the static array they are right again. What do I have to change?
Greets and thanks in advance!
Edit: I also noted that the TF_Tensor* input_value holds totally different values for both cases (for dynamic it has many 0 and nan entries). Is there a way to solve this by using a std::vector<std::vector<float>>?
Respectively: is there any valid way pass a consecutive dynamic 2d data structure to a function as void*?
In argument 4 you see the "normalizedInputs" array. When I run my program now, the calculated results are totally wrong.
The reason this doesn't work is because you are passing the pointers array as data. In this case you would have to use normalizedInputs[0] or the equivalent more explicit expression &normalizedInputs[0][0]. However there is another bigger problem with this code.
Since you are using new inside a loop you won't have contiguous data which TF_NewTensor expects. There are several solutions to this.
If you really need a 2d-array you can get away with two allocations. One for the pointers and one for the data. Then set the pointers into the data array appropriately.
float **normalizedInputs = new float* [noCellsPatches]; // allocate pointers
normalizedInputs[0] = new float [noCellsPatches*no_input_sizes]; // allocate data
// set pointers
for (int i = 1; i < noCellsPatches; ++i) {
normalizedInputs[i] = &normalizedInputs[i-1][no_input_sizes];
}
Then you can use normalizedInputs[i][j] as normal in C++ and the normalizedInputs[0] or &normalizedInputs[0][0] expression for your TF_NewTensor call.
Here is a mechanically simpler solution, just use a flat 1d array.
float * normalizedInputs = new float [noCellsPatches*no_input_sizes];
You access the i,j-th element by normalizedInputs[i*no_input_sizes+j] and you can use it directly in the TF_NewTensor call without worrying about any addresses.
C++ standard does its best to prevent programmers to use raw arrays, specifically multi-dimensional ones.
From your comment, your statically declared array is declared as:
float normalizedInputs[noCellsPatches][no_input_sizes];
If noCellsPatches and no_input_sizes are both compile time constants you have a correct program declaring a true 2D array. If they are not constants, you are declaring a 2D Variable Length Array... which does not exist in C++ standard. Fortunately, gcc allow it as an extension, but not MSVC nor clang.
If you want to declare a dynamic 2D array with non constant rows and columns, and use gcc, you can do that:
int (*arr0)[cols] = (int (*) [cols]) new int [rows*cols];
(the naive int (*arr0)[cols] = new int [rows][cols]; was rejected by my gcc 5.4.0)
It is definitely not correct C++ but is accepted by gcc and does what is expected.
The trick is that we all know that the size of an array of size n in n times the size of one element. A 2D array of rows rows of columnscolumns if then rows times the size of one row, which is columns when measured in underlying elements (here int). So we ask gcc to allocate a 1D array of the size of the 2D array and take enough liberalities with the strict aliasing rule to process it as the 2D array we wanted. As previously said, it violates the strict aliasing rule and use VLA in C++, but gcc accepts it.

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.

initialize an int[][] with new()

I am a c++ newbie. While learning I came across this.
if I have a pointer like this
int (*a)[2][3]
cdecl.org describe this as declare a as pointer to array 2 of array 3 of int:
When I try
int x[2][3];
a = &x;
this works.
My question is how I can initialize a when using with new() say something like
a = new int [] [];
I tried some combinations but doesn't get it quite right.
Any help will be appreciated.
You will have to do it in two steps - first allocate an array of pointers to pointers(dynamically allocated arrays) and then, allocate each of them in turn. Overall I believe a better option is simply to use std::vector - that is the preferred C++ way of doing this kind of things.
Still here is an example on how to achieve what you want:
int a**;
a = new int*[2];
for (int i =0; i< 2;++i){
a[i] = new int[3]
}
... use them ...
// Don't forget to free the memory!
for (int i = 0; i< 2; ++i) {
delete [] a[i];
}
delete [] a;
EDIT: and as requested by Default - the vector version:
std::vector<std::vector<int> > a(2, std::vector<int>(3,0));
// Use a and C++ will take care to free the memory.
It's probably not the answer you're looking for, but what you
need is a new expression whose return type is (*)[2][3] This
is fairly simple to do; that's the return type of new int
[n][2][3], for example. Do this, and a will point to the
first element of an array of [2] of array of [3] int. A three
dimensional array, in sum.
The problem is that new doesn't return a pointer to the top
level array type; it returns a pointer to the first element of
the array. So if you do new int[2][3], the expression
allocates an array of 2 array of 3 int, but it returns
a pointer to an array of 3 int (int (*a)[3]), because in C++,
arrays are broken (for reasons of C compatibility). And there's
no way of forcing it to do otherwise. So if you want it to
return a pointer to a two dimensional array, you have to
allocate a three dimensional array. (The first dimension can be
1, so new [1][2][3] would do the trick, and effectively only
allocate a single [2][3].)
A better solution might be to wrap the array in a struct:
struct Array
{
int data[2][3];
};
You can then use new Array, and everything works as expected.
Except that the syntax needed to access the array will be
different.

Dynamic array allocation in C++ question

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.

C++ -- Pointers to Arrays -- Arrays of Pointers

I notice this has caused confusion for several people, but after reading a couple of posts on here and the cplusplus tutorial my brain is still scrambled.
Suppose I have the following variables in a header file -
int numberOfLinePoints;
D3DXVECTOR3* line; //confused as to what it is
Then in the implementation C++ file I initialize them as follows -
//both initialized in constructor
numberOfLinePoints = 25;
line = new D3DXVECTOR3[numPoints]; //array of pointers?
What does my line variable now represent?
As far as I can tell from reading links on stackoverflow it should represent an array of pointers. I then read the following however...
(1) Pointers for Beginners
...where (A) arrays of pointers, and (B) pointers to arrays, are both discussed. This left me confused once again as they both seem to work similarly.
The fact that I define my pointers in a seperate location to where I allocate (correct?) them seems to be where my confusion stems from. Am I correct that this is an array of pointers to D3DXVECTOR3 objects?
To finish - if variable line holds information about one line segment, how would I create an array of line segments? I currently have the following -
//HEADER FILE
int numberOfLineSegments;
D3DXVECTOR3** lineCollection; //array of pointers - each of which
//points to an array of pointers?
//CPP FILE
numberOfLineSegments = 8; //constructor
for(i = 0; i < numberOfLineSegments; i++) //initialization
{ //and allocation CORRECT?
lineCollection[i] = new D3DXVECTOR*[numPoints]; //of memory for Y/N
} //lineCollection
VOID createLineSegments(startPoint, endPoint) //could return array instead
{
//pseudo to generate one line segment
while != numberOfLinePoints
line[sentinel++] = interpolate(startPoint, endPoint, time_T)
//pseudo to generate array of line segments
while != numberOfLines
lineCollection[sentinel++] = line
}
Any help is much appreciated.
Your first example:
int numberOfLinePoints;
D3DXVECTOR3* line; //confused as to what it is
Declares a simple pointer to a D3DXVECTOR3. A pointer can be initialized in two ways. First:
line = new D3DXVECTOR3;
This creates a single D3DXVECTOR3 and makes line point to that object. Second:
line = new D3DXVECTOR3[numberOfLinePoints];
This creates an array of D3DXVECTOR3s and makes line point to the first element of that array. You can then use pointer arithmetics to access other elements in that array.
If you declare you pointer as double pointer:
D3DXVECTOR3** line;
You simply create another level of indirection.
int numberOfLinePoints;
D3DXVECTOR3* line; //confused as to what it is
//both initialized in constructor
numberOfLinePoints = 25;
line = new D3DXVECTOR3[numPoints]; //array of pointers?
line is an array of D3DXVECTOR3. It would be an array of pointers if D3DVECTOR3 is itself a pointer, however. Since I don't know the C++ D3D headers very well, I'm not sure.
D3DXVECTOR3** lineCollection;
Is an array of pointers, each pointer likely being a pointer to a line (that is, an array of D3DXVECTOR3).
You have two options. Memorywise, the best would be to set each entry in lineCollection to just point to the corresponding line. This is safe if you either know the lines aren't going to change (and aren't going to be freed), or if they do change you want the changes to be reflected immedaitely inside your collection.
The other option would be to create a new array for each entry in lineCollection, and copy the points from each line into this new array.
There is no correct answer, it depends on the functionality you want.
(Attempting to answer the first part of the question as succinctly as possible without introducing other issues.)
C++ (and C) uses pointers to a single item in an array as a handle for the full array. However, some pointers don't point to items in an array! You have to make the distinction between points-to-single-item and points-to-item-in-array yourself.
int length = 8;
D3DXVECTOR3* line = new D3DXVECTOR3[length];
The new[] operator returns a pointer to the first item in the array it allocates, and this assigns that value to line. Notice that because pointers don't make the distinction of single-item vs. item-in-array:
you have to store the length separately
you have to be careful you use correct indices with pointers ("line" above)
you are better off using a "real" container type, such as:
std::deque, std::vector, etc.
std::tr1::array (aka boost::array)
(The last bullet point doesn't mean you never use pointers, you just don't use them when these containers are more appropriate.)
D3DXVECTOR3 line; // Line is a D3DXVECTOR3
D3DXVECTOR3 * line; // Line is EITHER a pointer to D3DXVECTOR3 OR an
// array of D3DXVECTOR3
D3DXVECTOR3 ** line; // Line is an array of pointers to D3DXVECTOR3 OR
// an array of array of D3DXVECTOR3
This is because an array is no specific structure in memory. It is just a bunch of D3DXVECTOR3 in a row. So pointing to the first element, and you get access to all of the others.
So, having
D3DXVECTOR3** lineCollection; // An array of pointers ORĀ an array of array!
new D3DXVECTOR[numPoints]; // A pointer to an array of D3DXVECTOR
lineCollection[i] // A pointer to an array
You initialize it by:
lineCollection[i] = new D3DXVECTOR[numPoints]; // No extra *
Yet: try to use the STL (like std::vector) instead of ugly C/Java style arrays. If you can, avoid declaring on the heap (using 'new'), but rather declaring on the stack:
D3DXVECTOR a, b, c; // a, b, and c ARE D3DXVECTOR, not pointers
std::vector<D3DXVECTOR> lines;
lines.push_back(a);
lines.push_back(b);
lines.push_back(c);
// equivalently: (you can push_back without temporaries)
std::vector<D3DXVECTOR> lines;
lines.push_back(D3DXVECTOR());
lines.push_back(D3DXVECTOR());
lines.push_back(D3DXVECTOR());
This will avoid manual memory management; it's more readable. You might not be able to always use that comfort (the way your code is organized). And if someone says something about performances, for now, don't worry. First get something working without segfaults nor memory leaks.
line = new D3DXVECTOR3[numPoints];
line holds the memory address of the first element of the array of D3DXVECTOR3.
I.e. line is a pointer to the first element of the array.
This article should clarify it.
Just look at this simple example :
case 1:
int *p = new int [N];
Here p is pointer to array of N integers and p stores starting address of the array.
case 2:
int **p = new int *[N]; //p is a pointer to pointers holding integers used for 2D array.
for(int i=0 ; i<N ; i++)
{
p[i] = new int [N]; // each element is pointer to array of integers.
}
It is applicable to all kinds of user defined types.