C++ 2DArray Objects; Pointers and Array Problems - c++

This problem is from a solved problem in my old question, which is from:
C++ Inserting 2D array Object into another 2D array Object
But also created a new problem for me. Please read the question and the solution in the link to understand my problem. The solution in the previous question was to make my Data Member Function into a pointer to pointer, to allow the pass into the other Data Member Function. But while fixing that, the first Data Member Function which is smallerArray.extractPiece() now only return address of the pointer to the pointer and not the content of those pointers. I need the content in order for my 2nd Data Member Function largerArray.extractArray(result) to work properly, as I attempt run the code and gave an Window Error, and not a Compile Error.
Does anyone know how to extract the content of the smallerArray.extractPiece() and instead of getting of the address, and is there isn't, does anyone have any other methods of creating a 2D-Array Object?

void Grid::extractArray( int** arr )
{
for(int i = 0; i < xGrid ; ++i) {
for (int j = 0; j < yGrid ; ++j) {
squares[i][j] = arr[i][j];
}
}
}
The smaller array int**arr does not have as many elements as the Grid.
xGrid and yGrid are too large to use as indices for arr[][].
You must pass the complete smaller array object into the extractArray() function and use the sizes from this object for the copy function.
void Grid::extractArray( const Piece & piece)
{
for(int i = 0; i < piece.xGrid ; ++i) {
for (int j = 0; j < piece.yGrid ; ++j) {
squares[i][j] = arr[i][j];
}
}
}

Right now, your problem seems a bit underspecified. How large of a 'piece' do you expect from the smaller array, and where in the larger array do you want to insert it?

It may make things easier if you create a 2D array object or class (or struct)
class BaxMatrix {
public:
int m_Data[4][4];
}
with a little work you could build dynamic structures or use STL structures as desired.
The data, and the reference to the data are two different animals. It's best for you to clarify each of their roles in your thinking, before proceeding forward.

Related

I want to declare a pyramid like structure in C++ in a particular way but cannot

I am essentially trying to declare something like this but I am unable to because of "too many initializer variables".
int** a = { {1},{2,3},{3,4,5} };
As a side question, if this were to work with some slight modification would it have the size of 9 (3x3) or 6 (1+2+3)?
I can implement this behavior with vectors such as the following, but I am curious as to why can't I do it more directly.
vector<int*>a = vector<int*>();
for (int i = 0; i < 20; i++)
{
a.push_back(new int[i]);
for (int j = 0; j <= i; j++)
a[i][j] = i+j;
}
Using a double pointer in C++ statically has a different memory arrangement than using new dynamically. The difference is that a static ** takes continuous memory automatically at compile time, where a dynamic one will not. Static multidimensional arrays are stored continuously, as discussed here.
Related: my question here.
Since your array cannot be stored continuously, it cannot be declared statically.

Dynamic 2D array without using new

I've been posed with creating a dynamic 2D array in C++ without using new in C++. I have been trying for a while to make something work but I'm clueless as to what I'm supposed to do.
Edit: Sorry, should have been more specific. Just to be transparent, yes it is homework, and no I don't want it solved I just want to be pointed (no pun intended) in the right direction to code it myself.
The order, for reference, is as follow: Develop a console application to create a type int matrix of size m x n using pointers. The user must input the values for the size of the matrix from the keyboard and its contents must be randomly generated (1 - 100). Then, the transpose of the matrix must be calculated and shown (it's necessary to create classes).
We can't use new, nor vector, as we have to do it just via pointers with uni-dimensional arrays. So far I created a class that represent the "rows", and another class which represents the "columns". The columns go into the rows and the rows go into another class called matrix. That was the idea but was having trouble implementing it.
new is the only way to create dynamic objects or arrays in standard C++. So, depending on how you interpret the task, it could be considered impossible.
If we assume that it is OK for you to call a standard function that internally calls new, then the problem is solvable. A commonly used way to create a dynamic array in C++ is to use std::vector. Elements of std::vector may not be arrays however, so a 2D dynamic array is not technically possible using it. One workaround is to wrap the array within a class, and use the class as element of the vector. There is a standard template for such array wrapper: std::array. An example of a vector of array wrappers:
std::vector<std::array<type_of_element, 10>> name_of_vector(number_of_arrays);
The elements of the arrays within the dynamic array managed by the vector will have effectively the same layout as a 2D array would.
malloc did the trick. Here is the code I used to test it. It was a bit convoluted to figure out how to write the matrix loop but once I got it down I realized how obvious it was.
Matriz::Matriz(int numFil, int numCol)
:numFil(numFil), numCol(numCol)
{
mat = (int *)malloc(numFil * numCol * sizeof (int));
int c = 0;
for(int i = 0; i < numFil; i++)
{
for(int j = 0; j < numCol; j++)
{
*(mat + i * numCol + j) = ++c;
}
}
}
void Matriz::printMat()
{
for(int i = 0; i < numFil; i++)
{
for(int j = 0; j < numCol; j++)
{
std::cout << *(mat + i*numCol + j);
}
std::cout << std::endl;
}
}

How to copy-by-value (not by reference) a CPLEX IloArray, the easy way

I work with CPLEX and C++ via Concert Technology and a recurrent issue I am encountering is that internally the IloArray structures seem to be overloaded vector structures with copy-by-reference operators. Which I must acknowledge is a quite neat and memory efficient way of handling the array structures.
Yet... This implies that making IloIntArray Array_copy = Array, for a previously declared and initialized IloIntArray Array, will make a reference copy of Array into Array_copy. Hence, any change in Array is automatically transferred to Array_copy. The same applies to multi-dimensional IloArray structures via the add() routine.
Let us say, for instance, that I need to populate a 2D IloArray<IloIntArray> Array2D(env), inside a for-loop indexed in i = 1 to iSize, storing in each position of Array2D[i], from i = 1 to iSize, the values of Array which will be different at each iteration of the loop. Making either:
Array2D[i].add(Array) or,
Array2D[i] = Array, assuming Array2D i-dimension was initially set to be of size iSize.
Fails to make the intended copy-by-value, since each time, a copy-by-reference is made to the elements of the i-dimension and you end up with all identical elements, equal to the last value of Array.
Now, besides, making my own copy-by-value operator constructor (Option I) or a copy routine (Option II) receiving, both, the origin and destination arrays as well as the position of the destination array (e.g. multi-dimensional array) where the origin array is to be copied.
Is there another way to make the copy-by-value? In any case, can you help me decide which one of these options is more neat and/or memory efficient? Intuitively I deem Option I to be the more efficient, but I don't know how to do it...
Thanks in advance for your help
Y
So far, I am solving my own issue by implementing a copy() function.
I have typedefed my multi-dimensional arrays as follows:
typedef IloArray<IloIntArray> Ilo2IntArray; and typedef IloArray<IloNumArray> Ilo2NumArray and so on for three or four dimensional integer or numeric arrays.
An example of my Ilo3IntArray copy(Ilo3IntArray origin) overload of the copy function I am using as a patch to make copy-by-value copies, is as follows:
Ilo3IntArray copy(Ilo3IntArray origin) {
IloInt iSize = origin.getSize();
Ilo3IntArray destination(env, iSize);
IloInt jSize = origin[0].getSize();
IloInt zSize = origin[0][0].getSize();
for (IloInt i = 0; i < iSize; i++) {
destination[i] = Ilo2IntArray(env, jSize);
for (IloInt j = 0; j < jSize; j++) {
destination[i][j] = IloIntArray(env, zSize);
for (IloInt z = 0; z < zSize; z++) {
destination[i][j][z] = origin[i][j][z];
}
}
}
return destination;
// Freeing Local Memory
destination.end();
}
Your comments and/or better answers are welcome!!!

How to call objects method from list of pointers to objects, which is in a vector?

I would like to ask how to call objects method (getName and get that name) if my object pointer list is in a vector which is in inner class of my class (this is called inner/nested) to hide private variables and methods. Here is what I wrote so far. I have no idea how to print out all of the objects:
bool Program::checkCategory(string name){
vector<Category> *ptr = &(impl->categories);
int i;
for (i = 0; i < ptr->size(); i++){
cout << ptr->at(i).getName() << endl;
}
return 0;
}
The small snippet you included has several problems. By decreasing order of importance:
You need a semicolon, not comma, before i++ in the for loop.
If the vector really holds pointers to objects, then you need to call ptr->at(i)->getName(), not ptr->at(i).getName(). In that case you also (most likely) need to declare the vector as vector<Category*>, not vector<Category>.
There is no need to use a pointer to access the vector. If you want a shorter name for the vector, you can use a reference, vector<Category>& vec = impl->categories. This makes it clear to the reader that you are only referencing a single vector rather than an array of vectors, and it removes the need to dereference the vector for each method call.
Not sure if this is the full extent of your issue (looks mostly good) but I think you need a semicolon:
You have:
i = 0; i < ptr->size(), i++
but you need it after size rather than comma:
i = 0; i < ptr->size(); i++

proper memory allocation for a 2D array in a class in C++

I am writing a C++ class that uses some fixed arrays, as well as some dynamically allocated arrays.
I was wondering if anybody can guide me for the proper way to allocate memory for the dynamic arrays , probably in the constructor/deconstructor, and also if I need to explicitly call them to make sure I don't get a seg fault.
Here is a simplified version of the related part of my code:
class Network {
public:
int n_nodes;
int user_index[MAX_USERS]; //a fixed array
int adjacency_matrix[][MAX_ITEMS];
//Network(int n_node, int** adjacency); //I would rather to set the element s in a function other than the constructor
Initializer(int n_node, int** adjacency);
~Netowrk();
}
So here are my specific question for this class:
1 - Can I have the 2D array adjacency_matrix[][] with undecided number of rows and columns until it's set by the user in the initializer function?
2 - where should I delete the 2D array? should I write it in the deconstructor? Should I call the deconstructor explicitly? Is there anything else I need to destroy in the deconstructor?
1 - Can I have the 2D array adjacency_matrix[][] with undecided number of rows and columns until it's set by the user in the initializer function?
Yes. The best way to do this, however, is not to use arrays at all. Instead, use std::vector, which manages the memory for you. There are two ways that you can do this. If you actually want to be able to use the [row][column] syntax to access elements, you'll need to use two dimensions of std::vectors:
std::vector<std::vector<int> > adjacency_matrix;
Once you know the dimensions, you can populate it:
adjacency_matrix.assign(rows, std::vector<int>(columns));
It is often easier to use a single-dimensional array (or a std::vector<int>) containing all of the elements and use row * row_count + column to access the element at index (row, column). This way, there are fewer dynamic allocations. You can wrap up the logic of accessing elements into a couple of helper functions.
2 - where should I delete the 2D array? should I write it in the deconstructor?
You don't have to delete anything if you use a std::vector. It cleans itself up.
Should I call the [destructor] explicitly?
No.
Is there anything else I need to destroy in the [destructor]?
Ideally, no. If you use the Standard Library containers, like std::vector and smart pointers, you shouldn't have to clean anything up. You should avoid trying to manage resources on your own in C++: there are library facilities to do this tedious task for you and you should take advantage of them.
1 - Can I have the 2D array adjacency_matrix[][] with undecided number of rows and columns until it's set by the user in the initializer function?
Yes you can. For example:
int* adjacency_matrix_;
int* getAdjacency(int i, int j)
{
if (!adjacency_matrix_)
return 0;
else
return adjacency_matrix_ + i*n_nodes + j;
}
Network()
: n_nodes(0),
adjacency_matrix_(0)
{}
void Initializer(int n_node, int** adjacency)
{
adjacency_matrix_ = new int[n_nodes * n_nodes];
// Copy over data.
}
As to whether you should, that depends on whether you have a reason for not using std::vector<>.
2 - where should I delete the 2D array? should I write it in the deconstructor?
Should I call the deconstructor explicitly?
Is there anything else I need to destroy in the deconstructor?
Yes, definitely free in the destructor using array operator delete:
~Network()
{
delete [] adjacency_matrix_;
}
No, your destructor will be called whenever the Network object itself goes out of scope. It is (very) rarely necessary to make an explicit destructor call.
No, all a destructor needs to explicitly release is whatever your explicitly acquire.
You may like the example matrix class I wrote in an answer to another question
The question itself was about good C++ design practices, but the chosen example was a multi-dimensional array.
There are several ways to do this.
The easiest way is to use vectors, and if you don't like to manage your own memory, this is perfect for you. However, because I like to manage my own memory, and I have found this method to be slow and cumbersome at times, I have learned of other ways.
The fastest way is to allocated a one dimensional array and treat it as you would a two dimensional array. Here is an example:
int *array = new int[width*height];
int get_array(int column, int row)
{
return array[row*width + column];
}
delete [] array;
This can be generalized to the nth-dimension:
int *array = new int[w1*w2*...*wn];
int get_array(int i1, int i2, ..., int in)
{
return array[in*(w1*w2*...*w(n-1)) + i(n-1)*(w1*w2*...*w(n-2)) + ... + i2*w1 + i1];
}
delete [] array;
If you want to be able to have different widths for each row, then you can make an array of pointers. This solution is slow to initialize and clean up, but flexible, tunable, and has relatively fast execution time. It can also be extremely dangerous if you make a mistake though.
int **array = new int*[height];
for (int i = 0; i < height; i++)
array[i] = new int[width(i)];
at which point, to access it, all you have to do is the customary
array[i][j]
however, to free this array you have to do it row by row
for (int i = 0; i < height; i++)
delete [] array[i];
delete [] array;
This can also generalize to the nth dimension.
int **....*array = new int**...*[w1];
for (int i1 = 0; i1 < w1; i1++)
{
array[i1] = new int**..*[w2];
for (int i2 = 0; i2 < w2; i2++)
{
array[i1][i2] = new int**.*[w3];
...
for (int in = 0; in < wn; in++)
array[i1][i2]...[in] = new int[wn];
}
}
for (int i1 = 0; i1 < w1; i1++)
{
for (int i2 = 0; i2 < w2; i2++)
{
...
for (int in = 0; in < wn; in++)
delete [] array[i1][i2]...[in];
...
delete [] array[i1][i2];
}
delete [] array[i1];
}
delete [] array;
This kind of setup tends to wreak havoc on memory. Just a two dimensional array of these would result in width+1 separate arrays to be malloc-ed. It would be faster to just malloc one big array and figure out the indices yourself.