Print values in a struct array, C++ - c++

I have an imposed .hpp containing theses things :
enum class TileType : uint16_t
{
EMPTY = 0,
BLOCK = 1,
OBSTACLE = 2,
EVIL_DUDE = 3,
EVIL_SHOOT = 4,
MY_SHOOT = 5,
POWERUP = 6,
OTHER = 7
};
and
struct GetMap
{
CommandType type;
uint16_t width;
uint16_t height;
TileType tile[0];
} __attribute__((packed));
My question is, after creating the variable :
GetMap *map = new GetMap[(10 * 10) * sizeof(TileType)];
and filled it with values like this :
map->tile[(y * 10) + x] = TileType::BLOCK;
How can I print the entire GetMap's tiles values on terminal ? I've thinked of using casts, but I have some problems with them.

Related

C++. Low level graphics. Polygon mesh data reading via classes. Need elaboration on the code of the constructor

I have been studying C++ and low-level graphics and currently have questions on this code from https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-polygon-mesh.
class PolygonMesh : public Object
{
public:
PolygonMesh(uint32_t nfaces, int *fi, int *vi, Vec3f *p) :
numFaces(nf), faceIndex(NULL), vertexIndex(NULL), P(NULL)
{
// compute vertArraySize and maxVertexIndex
uint32_t vertArraySize = 0;
uint32_t maxVertexIndex = 0, index = 0;
for (uint32_t i = 0; i < numFaces; ++i) {
vertArraySize += nv[i];
for (uint32_t j = 0; j < fi[i]; ++j)
if (vi[index + j] > maxVertexIndex)
maxVertexIndex = vi[index + j];
index += fi[i];
}
maxVertexIndex += 1;
pts = std::unique_ptr<Vec3f []>(new point[maxVertexIndex]);
for (uint32_t i = 0; i < maxVertexIndex; ++i) P[i] = p[i];
vertexIndex = std::unique_ptr<uint32_t []>(new int[maxVertexIndex]);
for (uint32_t i = 0; i < maxVertexIndex; ++i) vertexIndex [i] = vi[i];
faceIndex = std::unique_ptr<uint32_t>(new int[numFaces]);
for (uint32_t i = 0; i < numFaces; ++i) faceIndex[i] = fi[i];
};
~PolygonMesh() { /* release memory */ ... }
bool intersect(...) const { ... }
void getSurfaceData(...) const { ... }
uint32_t numFaces; //number of faces
std::unique_ptr<uint32_t []> faceIndex; //face index
std::unique_ptr<uint32_t []> vertexIndex; //vertex index
std::unique_ptr<Vec3f []> P;
};
int main(...)
{
...
uint32_t numFaces = 2;
uint32_t faceIndex[2] = {4, 4};
uint32_t vertexIndex[8] = {0, 1, 2, 3, 0, 3, 4, 5};
Vec3f P[6] = {
Vec3f (-5, -5, 5), Vec3f ( 5, -5, 5),
Vec3f ( 5, -5, -5), Vec3f (-5, -5, -5),
Vec3f (-5, 5, -5), Vec3f (-5, 5, 5),
};
PolygonMesh *mesh = new PolygonMesh(numFaces, faceIndex, vertexIndex, P);
...
}
The website (the author) says :
The point list, face and vertex index array are passed to the constructor of the MeshPolygon class as well as the number of faces. However we don't know how many points are in the point array. To find out, we look for the vertex with the maximum index value in the vertex index array (lines 13-14). The first element of an array in C++ start at 0, therefore the total number of vertices in the point list is the maximum index value plus 1 (line 17).
So, it is about getting data from polygon mesh! Several questions puzzle me :
Above it says, "...we don't know how many points are in the point array..." In my understanding, why just not read the size of the P array that is being passed from the main() ? That is supposed to be the size of the array, or...?
If my understanding correct, then in the PolygonMesh(..) constructor what happens is deep copying of pointers(and all the values those addresses' possess) ? Is it right? I am asking , because I have just learned( or read) recently about smart pointers, std::move and r-values references. Also, in the code, they don't std::move all the pointers from main to the class object because we want to save those original data (pointers), right?
Is it correct that in order to find Vertex Array Size in the above code for the class object, we could just read the maximum value of uint32_t vertexIndex[8], i.e maximum vertexIndexArray is the total number of vertices?
I assume in line 11 it must be vertIndexArraySize += fi[i]; instead of vertArraySize += nv[i]; because I have no idea where does nv come from what what it means...
Thank you all for your genuine help !

queue.front() in C++ returns a strange value

I'm coding in C++ and making use of the library.
My code goes something like this:
struct request {
int order;
float size;
};
typedef struct request req;
.. ...
std::queue <req> wait_queue;
// ...
for (int i = 0; i < 5; i++) {
req r;
r.order = i + 1;
r.size = 100;
wait_queue.push(r);
}
// ...
if (!wait_queue.empty()) {
req r = wait_queue.front();
// do something...
}
Where the req r do not conflict because they're defined in different functions in actuality.
Now I know the variables are saved correctly because when I run gdb and type p wait_queue it shows:
(gdb) $1 = std::queue wrapping: std::deque with 5 elements = {{order = 1, size = 100}, {order = 2, size = 100}, {order = 3,
size = 100}, {order = 4, size = 100}, {order = 5, size = 100}}
But after r = wait_queue.front(), p r shows:
(gdb) $2 = {order = 6417952, size = 0}
So I want to know how this can happen, and what I can do to make sure r will hold {order = 1, size = 100}.
Thanks in advance!

Use a member of struct vector in nested classes

I have written some codes like this
struct connectedGrids
{
int Coord[3];
enum faceOrien_Type
{
xNeg = 0,
xPos = 1,
yNeg = 2,
yPos = 3,
zNeg = 4,
zPos = 5
}faceOrien;
};
class face
{
public:
vector<connectedGrids> ConnectedGrids;
};
class grid
{
public:
face Face;
}
I have initialized an object Grid in the main.cpp
vector<vector<vector<grid> > > Grid = initGrid();
And I want to call the member of struct vector in nested classes like this:
Grid[i][j][k].Face.ConnectedGrids.faceOrien = 1;
But it gave me an error saying
faceOrien is not the member of std::vector<_Ty>
I'm new to C++, and I can't get out where is wrong :(
Well, ConnectedGrids is a vector, you declared it as
vector<connectedGrids> ConnectedGrids;
So, which of the connectedGrids structures inside that vector did you want to modify?
Grid[i][j][k].Face.ConnectedGrids is a vector. It surely doesn't have faceOrien member. You should add something to the vector and then access its elements, for example:
Grid[i][j][k].Face.ConnectedGrids.push_back(connectedGrids());
Grid[i][j][k].Face.ConnectedGrids[someIndex].faceOrien = 1;
ConnectedGruds is an vector<connectedGrids>, but you are treating it like a connectedGrids object.
Grid[i][j][k].Face.ConnectedGrids[0].faceOrien = 1;
// ^^^ assumes size > 0

Passing a structure by value, with another structure as one of its members, changes values of this member's members

Sorry for the confusing title, but it basically says it all. Here's the structures I'm using (found in OpenCV) :
struct CV_EXPORTS CvRTParams : public CvDTreeParams
{
bool calc_var_importance;
int nactive_vars;
CvTermCriteria term_crit;
CvRTParams() : CvDTreeParams( 5, 10, 0, false, 10, 0, false, false, 0 ),
calc_var_importance(false), nactive_vars(0)
{
term_crit = cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 50, 0.1 );
}
}
and
typedef struct CvTermCriteria
{
int type;
int max_iter;
double epsilon;
}
CvTermCriteria;
CV_INLINE CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon )
{
CvTermCriteria t;
t.type = type;
t.max_iter = max_iter;
t.epsilon = (float)epsilon;
return t;
}
Now, I initialize a CvRTParams structure and set values for its members :
CvRTParams params;
params.max_depth = 8;
params.min_sample_count = 10;
params.regression_accuracy = 0;
params.use_surrogates = false;
params.max_categories = 10;
params.priors = priors;
params.calc_var_importance = true;
params.nactive_vars = 9;
params.term_crit.max_iter = 33;
params.term_crit.epsilon = 0.1;
params.term_crit.type = 3;
Then call a function of an object, taking params in as a parameter :
CvRTrees* rt = new CvRTrees;
rt->train(t, CV_ROW_SAMPLE, r, 0, 0, var_type, 0, params);
What happens now ? Values of...
params.term_crit.max_iter
params.term_crit.epsilon
params.term_crit.type
have changed ! They are no longer 33, 0.1 and 3, but something along the lines of 3, 7.05541e-313 and 4, and this, for the whole duration of the CvRtrees::train() function...
By the time I finished writing this question I found the answer. So I figured I'd post anyway if someone comes across the same problem. The code itself wasn't wrong (or at least, it wasn't completely wrong). However I am using MacOS X and apple-gcc on a ppc processor (G5). I was using the -fast flag for optimization. Removing the -fast flag (leaving only -O3) solved the problem.

How to initialize 3D array in C++

How do you initialize a 3d array in C++
int min[1][1][1] = {100, { 100, {100}}}; //this is not the way
The array in your question has only one element, so you only need one value to completely initialise it. You need three sets of braces, one for each dimension of the array.
int min[1][1][1] = {{{100}}};
A clearer example might be:
int arr[2][3][4] = { { {1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4} },
{ {1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4} } };
As you can see, there are two groups, each containing three groups of 4 numbers.
Instead of static multidimensional arrays you should probably use one-dimensional array and calculate the index by multiplication. E.g.
class Array3D {
size_t m_width, m_height;
std::vector<int> m_data;
public:
Array3D(size_t x, size_t y, size_t z, int init = 0):
m_width(x), m_height(y), m_data(x*y*z, init)
{}
int& operator()(size_t x, size_t y, size_t z) {
return m_data.at(x + y * m_width + z * m_width * m_height);
}
};
// Usage:
Array3D arr(10, 15, 20, 100); // 10x15x20 array initialized with value 100
arr(8, 12, 17) = 3;
std::vector allocates the storage dynamically, which is a good thing because the stack space is often very limited and 3D arrays easily use a lot of space. Wrapping it in a class like that also makes passing the array (by copy or by reference) to other functions trivial, while doing any passing of multidimensional static arrays is very problematic.
The above code is simply an example and it could be optimized and made more complete. There also certainly are existing implementations of this in various libraries, but I don't know of any.
Here's another way to dynamically allocate a 3D array in C++.
int dimX = 100; int dimY = 100; int dimZ = 100;
int*** array; // 3D array definition;
// begin memory allocation
array = new int**[dimX];
for(int x = 0; x < dimX; ++x) {
array[x] = new int*[dimY];
for(int y = 0; y < dimY; ++y) {
array[x][y] = new int[dimZ];
for(int z = 0; z < dimZ; ++z) { // initialize the values to whatever you want the default to be
array[x][y][z] = 0;
}
}
}
Everyone seems to forget std::valarray. It's the STL template for flat multidimensional arrays, and indexing and slicing them.
http://www.cplusplus.com/reference/std/valarray/
No static initialization, but is that really essential?