C++ 2D dynamic array crash - c++

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++

Related

Invalid Pointer?

I recently learned about pointers, and have been working hard to really understand them. However, I have run into trouble. For class we had to write a function that would double an array x amount of times. I was able to write the function without any real problems, but I'm trying to implement it into an actual code and I continue to get invalid pointer errors. Here's the code:
#include <iostream>
using namespace std;
int *ArrayDoubling(int inputArray[], int initialSize, int numberToDouble);
int main(){
int arr[2] = {0,1};
int array_size = 2;
int number = 3;
ArrayDoubling(arr, array_size, number);
}
int *ArrayDoubling(int inputArray[], int initialSize, int numberToDouble){
for(int i=0;i<numberToDouble;i++){
int *array2 = new int[initialSize*2];
for(int i=0;i<initialSize;i++){
array2[i] = inputArray[i];
array2[i+initialSize] = inputArray[i]*2;
}
initialSize = initialSize*2;
delete []inputArray;
inputArray = array2;
}
return inputArray;
}
So what exactly is causing the problem, and how can I fix it? Also not sure if this will actually print the output of the Array, but I'm also trying to get that to happen. Thanks for any and all help!
The ArrayDoubling function calls delete[] on the inputArray argument. But you pass a pointer to an automatic array when you call it in main. Calling delete[] with a pointer that you didn't get from new[] has undefined behaviour.
To fix it, only use the function with dynamically allocated arrays.
Your inner loop is looping by the number of times to double, not the size of the array. For inputs where the size of the array is less than the number of times to double, you will be accessing out of range indices.
I am not quite sure what your intension is, but I think your second for loop should look like this:
for(int i=0;i<initialSize;i++)
The biggest problem with your code is this line: delete []inputArray;
inputArray was originally declared as int arr[2] = {0,1}; which should not be deleted. You can only delete variables which were created using keyword new.
Broadly speaking, your program is going to need to look something like this. Note that new[] happens outside of the population loops in ArrayRepeat so it is only called once and similarly delete[] will only be called once, on the same pointer that was created through new[].
// dynamically allocate an array which contains the first `N` elements of
// `array` repeated `repeats` times.
int * ArrayRepeat (int * array, size_t N, int repeats) {
int * result = new int[N * repeats];
assert(result); // Error check
// Loops to populate result goes here
return result;
}
int main (void) {
int arr[] = {0, 1};
int * repeated = ArrayRepeat(arr, 2, 3);
// Print the result
for (int i = 0; i < 2 * 3; ++i) {
printf("%d\n", repeated[i]);
}
delete[] (repeated);
return 0;
}

Pointer of Two dimensional array to function c++

Im kind of begginer in C++, just to programming in PHP and JAVA, I have problem to make a pointer to 2d array, then use this pointer in different function and cout values of [0] and [1].
There is part of my script.
int size_dd = 5;
int dd[size_dd][2];
for (int i = 0; i < size_dd; i ++)
{
dd[i][0] = 2 * i + 10;
dd[i][1] = 4 * i + 20;
}
I can read the dd[i][0] in main function but I cannot call them in function read(int* twodarray), as it returns int[int] and the 2nd parameter from array is lost.
Thing is that I need to make pointer to this array and call it in other function.
But the problem is when I handle *dd in to the function, it return that dd is int[int] value instead of int[int][int], how can I resolve it?
Your function should have following signature:
void fooByPtr(int(*arr)[5][6]) {
(*arr)[4][4] = 156;
}
// Call ex:
int dd[5][6];
fooByPtr(&dd);
You can also do it with reference and template:
void fooByRef(int (&arr)[5][6]) {
arr[4][4] = 156;
}
template<int N, int M>
void fooByRefTempl(int(&arr)[N][M]) {
arr[4][4] = 156;
}
Some other comments to your code (also the one from comment):
You can create arrays using constant values as sizes, so this is wrong:
int size_dd = 5;
and should be:
const int size_dd = 5;
in your fun_call you should dereference your array: (*dwu_wymiar) before indexing it.
finally, change funCall(int(*dwu_wymiar)[][2], to int(*dwu_wymiar)[5][2], as in my example above.

how to assign a multidimensional array to a structure?

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

Can't declare dynamic 2D array in C++ [duplicate]

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 8 years ago.
I've stuck on a problem - I can't declare 2D arrays in C++ using integers, written by user.
This code works fine-
cin>>m>>n;
int *array;
array=new int[m*n];
But I can't make this work -
cin>>m>>n;
int *array;
array=new int[m][n];
Any ideas how i can bypass it?
P.S. the error : cannot convert 'int ()[2]' to 'int' in assignment.
Change
cin>>m>>n;
int *array;
array=new int[m][n];
to
cin>>m>>n;
int **array;
array=new int * [m];
for ( int i = 0; i < m; i++ ) array[i] = new int[n];
array is int * and you try to assign int **... change array to int**.
2D array is actually array of arrays, so you need pointer to pointer.
That's because you can only use new to allocate 1D arrays. In fact, 2D arrays are also 1D arrays, where, in most systems, all rows are simply concatenated. That is called a row-major memory layout.
You can emulate 2D arrays with a 1D array. The index conversion is:
index1 = y * m + x
This also has much better performance than creating one array per row, as recommended in the "duplicate" link or in other answers.
Just as Domi said (but not index1=y*m+x but rather index1=x*n+y to emulate your desired notation):
int *array = new int [m*n];
int get (int x, int y) // emulates array[x][y] for array[m][n]
{
return array[x*n+y];
}
However, I think the real 2-dimensional allocation (as Vlad from Moscow showed you) is slower in creation (and needs a bit more memory), but quicker in accessing. Cause array[x*n+y] == *(array+x*n+y), wether array[x][y] == *(*(array+x)+y), so you have one multiplication less, but one dereferenciation more, in sum I think it's quicker.
You could also create a class:
class array2d
{
private:
int *data;
int mm, nn;
public:
array2d (int m, int n)
{
mm = m;
nn = n;
data = new int [m*n];
}
~array2d ()
{
delete[] data;
}
int *operator[] (int x)
{
return (data+x*nn);
}
};
With it you can use
array2d arr(10,10);
arr[5][7] = 1;
You can do this:
typedef int RowType[n];
RowType *array = new RowType[m];
doStuffWith(array[y][x]);
Or, even shorter (but harder to remember):
int (*array)[n] = new (int[m][n]);
Edit:
There is a catch in C++ that array sizes must be constant for the new operator, so you can only do this if n is const. This is not a problem in C (and the reason I forgot about this), so the following works even if n and m are not const:
RowType *array = (RowType*)malloc(m * sizeof(RowType));
Of course, you can work around this restriction in C++ by doing this, which works even if both m and n are dynamic:
RowType *array = (RowType*)new int[m * n];
The typedef free version would be this:
int (*array)[n] = (int (*)[n])new int[m *n];
Firstly I suggest you should use std::vector to avoid memory allocation / deallocation issues.
In case you want an array implementation, then you can declare array as a pointer to pointer to int.
cin >> m >> n;
int** array = new int* [m];
for ( int I = 0; I < m; I++ ) {
array[I] = new int[n];
}

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);