how to assign a multidimensional array to a structure? - c++

I am new to c++ and for my program I want to assign a 2d array pointer to structure. Code is
struct normal
{
double n_x, n_y;
};
This is the structure I defined and I want to assign a 2d array pointer in main like this:
normal **normal_cell;
*normal_cell = new normal[p];
for(int i=0;i<p;i++)
{
normal_cell[i] = new normal[4];
}
and this 2d pointer should be passed to a function. When I try to do this my program is not running. Can anyone help me out with this?

Just use normal_cell = new normal*[p] instead of *normal_cell = new normal[p]

In C++, we use vectors instead of arrays and pointers:
#include<vector>
using std:: vector;
struct normal
{
double n_x, n_y;
};
vector<vector<normal>> normal_cell;
void foo() {
int p=10;
normal_cell.resize(p);
for(int i=0;i<p;i++)
{
normal_cell.at(i).resize(4);
}
}

Just try it:
//if normal_cell[4][5]
const int m = 4; //row
const int n = 5; //column
normal **normal_cell = new normal*[m]; //new row
for(int i=0; i<m; ++i)
normal_cell[i] = new normal[n]; //new column

Related

Merging two sorted array on third by creating a new array on heap

I have a class array inside which I have declared an array its size and length. I am trying to merge two sorted arrays by creating the third array on the heap and both the sorted array will be merged on the third array. But whenever I create a new arr on heap the compiler gives me this error: request for member '..' in '..' which is of non-class type
class Array
{
public:
int A[10];
int length;
int Size;
};
void display(Array arr)
{
int i;
for(i=0;i<arr.length;i++)
{
cout<<arr.A[i]<<" ";
}
}
void Merge(Array *arr1,Array *arr2)
{
int i,j,k;
i=j=k=0;
int *arr3;
arr3=new int[10];
while(i<arr1->length && j<arr2->length)
{
if(arr1->A[i]<arr2->A[j])
arr3->A[k++]=arr1->A[i++];
else
arr3->A[k++]=arr2->A[j++];
}
for(;i<arr1->length;i++)
{
arr3->A[k++]=arr1->A[i];
}
for(;j<arr2->length;j++)
{
arr3->A[k++]=arr1->A[j];
}
}
int main()
{
Array arr1{{1,3,5,7},4,4};
Array arr2{{2,4,6,8},4,4};
Array *arr3;
arr3=Merge(&arr1,&arr2);
display(*arr3);
return 0;
}
The root cause of all your problems is that you use C-Style array with a magical size 10. Like in int A[10];. This is a major problem and should be avoided in C++.
Additionally, and the same, In C++ we usually do not use raw pointer for owned memories or newand such stuff.
Anyway. The design will never work, if the number of elements in both Array classes is greater then 5. Because then you will definitely get an out of bounds problem.
You must use a std::vector.
So, all bad. But I know that I will hear now, that the teacher said, no vector but new. The teacher should be fired or begin to teach C instead of C++.
Anyway again, I will fix the major bugs for you. But the sorting algorithm will work neither.
So,
If you want to return an Array, then change the signature of your function aand return an Array.
You do want to have a new Array, not new intes. So, please allocate a new Array instead.
Do not forget to release the newed Arrary at then end.
Set size and length of the new array.
Refactor your complete code.
Code example with some fixes:
#include <iostream>
class Array
{
public:
int A[10];
int length;
int Size;
};
void display(Array arr)
{
int i;
for (i = 0; i < arr.length; i++)
{
std::cout << arr.A[i] << " ";
}
}
Array* Merge(Array* arr1, Array* arr2)
{
int i, j, k;
i = j = k = 0;
Array *arr3 = new Array;
while (i < arr1->length && j < arr2->length)
{
if (arr1->A[i] < arr2->A[j])
arr3->A[k++] = arr1->A[i++];
else
arr3->A[k++] = arr2->A[j++];
}
for (; i < arr1->length; i++)
{
arr3->A[k++] = arr1->A[i];
}
for (; j < arr2->length; j++)
{
arr3->A[k++] = arr1->A[j];
}
arr3->length = arr1->length + arr2->length;
return arr3;
}
int main()
{
Array arr1{ {1,3,5,7},4,4 };
Array arr2{ {2,4,6,8},4,4 };
Array* arr3;
arr3 = Merge(&arr1, &arr2);
display(*arr3);
delete[]arr3;
return 0;
}

C++ array initialization by reference through function

I'm working on a project that requires many dynamically sized 2D arrays that need to be accessible across functions.
The code I'm working on uses pointers like double** dynArray for this.
R = ...; // ROWS of the matrix, unknown prior to runtime
C = ...; // COLUMNS of the matrix, unknown prior to runtime
double** dynArray;
After checking the existing code I found that the arrays are currently always being initialized like this:
double** dynArray = new double*[R];
for(int r=0; r<R; r++){dynArray[r] = new double[C];}
In order to improve the readability I would like to write a method to do the above.
Here's what I came up with to allocate
void initialize2D(double*** data, int R, int C){
(*dynArray) = new double*[R];
for(int r=0; r<R; r++){
(*dynArray)[r] = new double[C];
for(int c=0; c<C; c++){
(*dynArray)[r][c] = 0;
}
}
}
and free memory respectively:
void free2D(double*** data, int R, int C){
for(int r=0; r<R; r++){
delete[] (*data)[r];
}
delete *data;
}
I intended to use these methods like this:
R = ...; // ROWS of the matrix, unknown prior to runtime
C = ...; // COLUMNS of the matrix, unknown prior to runtime
double** dynArray;
initialize2D(&dynArray, R, C);
/* do stuff*/
free2D(&dynArray,R,C);
After implementing these functions I ran Valgrind and found that this qualifies as a
definitely lost, sometimes
possibly lost.
What is the problem, and what would be the proper way to initialize through a function by reference?
Write the functions the following way
double ** initialize2D( int R, int C )
{
double **dynArray = new double *[R];
for ( int r = 0; r < R; r++ )
{
dynArray[r] = new double[C]();
}
return dynArray;
}
void free2D( double **data, int R )
{
for ( int r = 0; r < R; r++ ) delete [] data[r];
delete [] data;
}
And call the functions the following way
double** dynArray = initialize2D( R, C );
/* do stuff*/
free2D( dynArray, R );
dynArray = nullptr;
Take into account that you could use standard container std::vector<std::vector<double>> instead of dynamically allocate the arrays yourself.
Assuming it is necessary to pass the pointer to the function to initialise it ...
void initialize2D(double*** data, int R, int C)
{
*data = new double*[R];
for(int r=0; r<R; r++)
{
(*data)[r] = new double[C];
for(int c=0; c<C; c++)
{
(*data)[r][c] = 0;
}
}
}
void free2D( double ***data, int R )
{
for ( int r = 0; r < R; r++ ) delete [] (*data)[r];
delete [] (*data);
*data = nullptr;
}
Personally, however, I wouldn't directly use dynamic memory allocation at all. Instead I'd do;
#include <vector>
// and in your code
void some_function()
{
std::vector<std::vector<double> > dynArray(R, std::vector<double>(C));
// use dynArray as if it is a 2D array. All elements dynArray[i][j]
// will be initialised to zero, for i = 0 to R-1 and j = 0 to C-1
dynArray[3][4] = 42; // assuming R > 3 and C > 4
// ALL memory allocated for dynArray will be released here automatically as it passes out of scope
}
The advantage of this is that the standard vector class will happily manage all memory allocation and deallocation for you.
It is easy enough to pass such vectors around by reference.
An alltogether better way to code what you have above is:
#include <vector>
std::vector<std::vector<double>> initialise2D(int r, int c)
{
std::vector<std::vector<double>> result(r);
for(int i=0; i<r; ++i) result[i].reserve(c);
return result;
}
void free2D(std::vector<std::vector<double>> &v)
{
v.clear();
}
you can then
auto dynArray = initialise3D(20, 30);
You should also note that you do not actually need free2D any longer. I kept it here only for you to see how much easier things have became.
You will also note that you can use vector in the same way as you used array. That is why there was no problem for me to write result[i] using square brackets, as if it were an array.

Assigning one 2D array to another

So in my program I have a function which passes into it a 2D array and I want to set another 2D array equal to that 2D array. I am coding this in C++ and can't quite get the syntax right. Right now I have the following:
void MyFunction(float **two_d_array){
float newArray[4][4];
//Set new array equal to two_d_array
}
two_d_array will also always be 4x4 so the dimensions themselves aren't an issue.
I hope you are not passing a two-dimensional array as a double pointer to your function.
Anyways, you can just write
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
newArray[i][j] = two_d_array[i][j];
If you have another two-dimensional array (and not an array of pointers), then simply use memcpy():
void foo(float arr[][4])
{
float newArray[4][4];
memcpy(newArray, arr, sizeof(newArray));
}
When you define a two dimentional array as
float a[4][4]
Its type is float [4][4].
if you want to pass float** to the function you can create your with float**
float** f = (float**) malloc(sizeof(float *)*4);
for(int i=0;i<4;i++){
f[i] = (float*) malloc(sizeof(float)*4);
}
//initialize
MyFunction(f);
And Myfunction will be similar
void MyFunction(float **two_d_array){
float newArray[4][4];
for(int i=0;i<4;i++){
float* one_d = & two_d_array[i][0];
for(int j=0;j<4;j++){
newArray[i][j] = one_d[j];
}
}
}
Yes, you must assign the second dimenson, and the first dimension passing by a integer parameter, it will look like this:
void foo(float arr[][4], int dim);

C++ Dynamic multidimensional array problem

I'm developing a 2d-platformer. Everything was fine until I've got some hard to solve problem. Level map is stored in dynamic multidemension array(char **map). It works fine, until I want to redefine it
Here's the part of code:
Map& Map::operator=(const Map& rhs)
{
if(width!=0||height!=0)
{
for(int i=0;i<width;i++)
delete[] map[i];
delete[] map;
} //deleting previously created array
height=rhs.height;
width=rhs.width; //receiving other map's size
map=new char* [width];
walkmap=new unsigned char* [width];
objmap=new char* [width];
for(int i=0;i<width;i++)
{
*(map+i)=new char[height];
} //creating new array
for(int h=0;h<height;h++)
for(int w=0;w<width;w++)
{
map[w][h]=rhs.map[w][h];
} //receiving new values
//...
}
Everything works fine for the first time, but when I need to redefine array for the second time my program crashes at the part, when array is receiving new values from another one. May be I miss something, but I can't find it! I was searching for this problem, but didn't find what I am doing wrong. Help me, please.
As always, Boost has an elegant and memory efficient multi-dimensional array class:
http://www.boost.org/doc/libs/1_39_0/libs/multi_array/doc/user.html
For example, to setup a 10 x 20 array of bool values:
boost::multi_array mtaFlagMatrix(boost::extents[10][20]);
Then to access its elements:
mtaFlagMatrix[2][6] = false; // indexes are zero-based - just like normal C arrays
...
if ( mtaFlagMatrix[2][6] )
{
...
}
Then, you can resize the array this way (existing values are preserved):
typedef boost::multi_array array_type;
array_type::extent_gen extents;
array_type A(extents[3][3][3]);
A[0][0][0] = 4;
A[2][2][2] = 5;
A.resize(extents[2][3][4]);
assert(A[0][0][0] == 4);
// A[2][2][2] is no longer valid.
This saved me a lot of time testing for extreme cases.
Your 2d array is not freeed properly. I advise you to use the Iliffe way of allocating 2d arrays which is faster and safer to use:
char** alloc_array( int h, int w )
{
typedef char* cptr;
int i;
char** m = new cptr[h];
m[0] = new char[h*w];
for(i=1;i<h;i++) m[i] = m[i-1]+w;
return m;
}
void release_array(char** m)
{
delete[] m[0];
delete[] m;
}
int main()
{
int r,c;
char** tab;
int width = 5;
int height = 3;
tab = alloc_array(height, width); /* column first */
for(r = 0;r<height;++r)
for(c = 0;c<width;++c)
tab[r][c] = (1+r+c);
for(r = 0;r<height;++r)
{
for(c = 0;c<width;++c)
{
printf("%d\t",tab[r][c]);
}
puts("");
}
release_array(tab);
}
This can be easily encapsulated in a neat 2d-array class or made to use std::vector instead of raw allocation. Prefer this way of doing 2d array as it is cache friendly , style provide the [][] access and is no slower and soemtimes faster than the polynomial 1d access.

C++ 2D dynamic array crash

Hi I'm having some problem with 2D dynamic array.
int main()
{
double **M;
int M_dimension;
int i;
M_dimension = 10;
M = new double *[M_dimension];
for (i=0;i<M_dimension;i++)
{
M[i] = new double[M_dimension];
}
M[0][0] = 1.0;
...
}
Program works but I'd like to initialize 2D array using such a function:
void initialize2D(double **M,int M_dimension)
{
int i;
M = new double *[M_dimension];
for (i=0;i<M_dimension;i++)
{
M[i] = new double[M_dimension];
}
}
Finally the program looks like this:
int main()
{
double **M;
int M_dimension;
int i;
M_dimension = 10;
initialize2D(M,M_dimension);
M[0][0] = 1.0; //crash
...
}
Unfortunately it crashes at M[0][0] = 1.0;
Thanks for any help or suggestions.
You are passing M by value, instead of by reference. initialize2D needs to change the value of the pointer-to-pointer M such that it points to the memory allocated
Try changing your function signature to this instead:
void initialize2D(double **&M,int M_dimension)
Or
void initialize2D(double ***M,int M_dimension) {
...
*M = new double *[M_dimension];
...
}
You need to pass a reference to double** instead of double** to function, otherwise the modification done to a pointer after assigning M the reslut of new get lost on exit from a function.
what the problem might be is where you declaring an integer parameter such as int M_dimension
void initialize2D(double **M,int M_dimension)
and then you initializing the dynamic array as:
M[i] = new double[M_dimension];
where it comes to contradiction because you declared the variable M_dimension as an integer and then you using it as a double
try it this way:
either change the data type of array or the M_dimension, so then both of them have the same data type.
hopefully this will help you out
Why don't you use std::vector or Boost.MultiArray
It would be quite easy exercise to define 2-dimension array as generic vector of vectors in C++