Converting 2D vector to 2D array - c++

It's been a while since I last visited arrays (I've been working with vectors recently) and I need to convert an 2D vector back into a 2D array because of a library I am using accepts the paramaters of type double array where the accessors of this array is foo[i][j] for example.
Here is my code:
double** setupHMM(vector<vector<double> > &vals, int N, int M)
{
double** temp;
temp = new double[N][M];
for(unsigned i=0; (i < N); i++)
{
for(unsigned j=0; (j < M); j++)
{
temp[i][j] = vals[i][j];
}
}
}
And with this, I get error: ‘M’ cannot appear in a constant-expression
I have also tried the following:
double** setupHMM(vector<vector<double> > &vals, int N, int M)
{
double** temp;
for(unsigned i=0; (i < N); i++)
{
temp[i] = new double[N];
for(unsigned j=0; (j < M); j++)
{
temp[j] = new double[M];
temp[i][j] = vals[i][j];
}
}
}
However, this produces a segmentation fault 11.
Could anyone suggest any advice, or, a better way to convert a vector to a 2D array..
Thanks

You were close. It should be:
double** setupHMM(vector<vector<double> > &vals, int N, int M)
{
double** temp;
temp = new double*[N];
for(unsigned i=0; (i < N); i++)
{
temp[i] = new double[M];
for(unsigned j=0; (j < M); j++)
{
temp[i][j] = vals[i][j];
}
}
}

A double pointer (double**) is not convertible to a 2D array.
double** temp;
temp = new double[N][M]; //invalid
double** temp;
temp = new double(*)[M];
It's a common misunderstanding to think that because an 1D array decays to a pointer that therefore a 2D array will decay to a double pointer. This is not true. The decay only happens with a single pointer.

replace
temp[i] = new double[N];
with
temp = new double*[N];
in the second code, and move it outside the loop

Related

2d arrays issue connected with passing a filled array

I'm working with c++ arrays and I found a problem. I can easily do the exercise using cin and filling array with for loop. But when I try to do it as filled array I got the error with too many initializer values. How to solve it?
#include <iostream>
using namespace std;
void func(int **arr, int row, int col)
{
for (int i=0; i<row; i++)
{
for(int j=0 ; j<col; j++)
{
cout<<arr[i][j]<<" ";
}
printf("\n");
}
}
int main()
{
int row = 2;
int colum = 2;
int** arr = new int*[row];
for(int i=0; i<row; i++)
{
arr[i] = new int[colum];
}
arr = {
{1,2},
{3,4}};
func(arr, row, colum);
return 0;
}
arr is a pointer
int** arr = new int*[row];
So it may be initialized with a braced list containing only one (assignment) expression.
For the allocated array of two elements you could write for example
int** arr = new int*[row];
for(int i=0; i<row; i++)
{
if ( i == 0 ) arr[i] = new int[colum] { 1, 2 };
else arr[i] = new int[colum] { 3, 4 };
}
or
int** arr = new int*[row];
for(int i=0, value = 1; i<row; i++)
{
arr[i] = new int[colum] { value++, value++ };
}
Pay attention to that you will need to free the dynamically allocated memory for the arrays.
Otherwise use the standard container std::vector<std::vector<int>> instead of the allocated dynamically arrays.

cleaner way of filling 0's in dynamic 2-D array in C++

int **C = new int*[rows];
for(int i = 0; i < rows; i++){
C[i] = new int[cols];
for(int j = 0; j < cols; j++){
C[i][j] = 0;
}
}
I'm creating dynamic 2-D array, but can we somehow initialize the array with 0's in all the entries without using inner loop?
If you use std::vector instead, it would simply be
std::vector<std::vector<int>> C(rows, std::vector<int>(cols));
You can do it with value initialization
int **C = new int*[rows]();
for(int i = 0; i < rows; i++)
{
C[i] = new int[cols]();
}
However a std::vector would be nicer (because of memory management).
One option is to use the std::fill function:
int **C = new int*[rows];
for(int i = 0; i < rows; i++)
{
C[i] = new int[cols];
std::fill(C[i], C[i] + cols, 0);
}
using namespace std::placeholders;
std::for_each(C, C + rows, std::bind(std::fill_n<int*, std::size_t, int>, _1, cols, 0));
Or if reused often:
auto fill_row = [] (int i) { return [=] (int* r) { std::fill_n(r, cols, i); }; };
std::for_each(C, C + rows, fill_row(0));

Allocate memory 2d array in function C++

I'm trying to dynamically allocate memory for a 2D array inside a function in C++.
A question exactly like this has been asked except that it is written using malloc and dealloc, so I was wondering if you could help me convert it to use new and delete. Here is the other question:
Allocate memory 2d array in function C
I tried changing it to the following code, but I'm getting errors.
void assign_memory_for_board(int ROWS, int COLS, int *** board) {
*board = new int**[ROWS];
for (int i = 0; i < ROWS; i++) {
(*board)[i] = new int*[COLS];
}
}
Here is the answer that worked using malloc and dealloc:
void allocate_mem(int*** arr, int n, int m)
{
*arr = (int**)malloc(n*sizeof(int*));
for(int i=0; i<n; i++)
(*arr)[i] = (int*)malloc(m*sizeof(int));
}
Thank you!
You have extra stars. The function should be
void assign_memory_for_board(int ROWS, int COLS, int *** board) {
*board = new int*[ROWS];
for (int i = 0; i < ROWS; i++) {
(*board)[i] = new int[COLS];
}
}
try it
int AllocMatrix(int ***K, int h, int c){
*K = new int *[h];
for(int i=0; i < h; i++){
*K[i] = new int[c];
}
if(K == NULL){
return 0;
}
cout<<"Avaiable!"<<endl;
return 1;
}

Copying a dynamically allocated 2D array

I have a question as follows:
I declared two pointer-to-pointer double-type variables **matrix1 and **matrix2 and allocate them by new operator to become 2D arrays.
First I used for loop to make matrix1 point to double-type data called element, then I copy matrix1 to matrix2, which means matrix2 points to element too. Then problem comes: I used delete operator to terminate matrix1 after copying, but then the values matrix2 point to became extremely strange. I think that was because after deleting matrix1, element terminates, so I think one of a solution is let matrix2 point to other address with the values same with element. But I don't know how to do this(copy element to new dynamic memories and won't disappear after deleting matrix1) in an efficient way, can somebody help me? thank you.
void MatCpy(double **InMat, double **OutMat, int NumOfRow, int NumOfCol)
{
for (int j = 0; j < NumOfRow; j++)
{
for (int i = 0; i < NumOfCol; i++)
{
OutMat[j][i] = InMat[j][i];
}
}
}
double **Malloc2D_Dbl(int row, int col)
{
double **data = new double*[row];
for (int i = 0; i < row; i++)
data[i] = new double[col];
return data;
}
void load(char *load_path, double **data, int height, int width) // function for loading
{
int i = 0, j = 0;
char buffer[30];
file_handle = fopen (load_path, "r");
for (int k = 0; k < width*height; k++)
{
fscanf (file_handle, "%s", &buffer);
j = k / width;
i = k % width;
data[j][i] = atof(buffer);
}
fclose (file_handle);
}
Sorry I am a noob....
More efficient than copying the individual elements is to use memcpy like this:
void MatCpy(double **InMat, double **OutMat, int NumOfRow, int NumOfCol) {
for(int j=0; j<NumOfRow; j++) {
memcpy(OutMat[j], InMat[j], NumOfCol*sizeof(double));
}
}

returning a two dimensional array from a function in c++ [duplicate]

This question already has answers here:
Returning multidimensional array from function
(7 answers)
Closed 9 years ago.
I want to use a two dimensional int array which is returned from a function
how should I define the function return value ?
I used int** but the compiler gave error:
int** tableCreator(){
int** table=new int[10][10];
for(int xxx=1;xxx<10;xxx++){
for(int yyy=1;yyy<10;yyy++){
table[xxx][yyy]=xxx*yyy;
}
}
return(table); //Here:cannot convert from 'int (*)[10]' to 'int **'
}
Try this:
#include <cstdio>
#include <cstdlib>
int** createTable(int rows, int columns){
int** table = new int*[rows];
for(int i = 0; i < rows; i++) {
table[i] = new int[columns];
for(int j = 0; j < columns; j++){ table[i][j] = (i+j); }// sample set value;
}
return table;
}
void freeTable(int** table, int rows){
if(table){
for(int i = 0; i < rows; i++){ if(table[i]){ delete[] table[i]; } }
delete[] table;
}
}
void printTable(int** table, int rows, int columns){
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
printf("(%d,%d) -> %d\n", i, j, table[i][j]);
}
}
}
int main(int argc, char** argv){
int** table = createTable(10, 10);
printTable(table, 10, 10);
freeTable(table, 10);
return 0;
}
You need the second loop to allocate a 2-d array in C and similar operation to free it. a two-D array is in essence an array of arrays so can be expressed as a pointer array. the loop initializes the arrays pointed to the pointers.
Clarifying as per conversation with #Eric Postpischil below: changed createTable to take row/column count for truly dynamic allocation.
int** table=new int[10][10];
this is wrong. you cannot allocate space for 2D dynamic array in this way in C/C++.
Meanwhile, you declared array size as 10, so indices are from 0-9, but you are trying to assign values to index 10 in your nested for loops, which is not right too.
You may do the following for allocation:
int** table = new int*[10];
for (int i = 0; i < 10; ++i)
{
table[i] = new int[10];
}
Usually, the type used to point to an array is a pointer to an element of the array. Since a two-dimensional array of int is an array of array of int, you want a pointer to array of int. The C++ syntax for this type is int (*)[N], for some dimension N. This code demonstrates:
#define N 10
int (*tableCreator())[N]
{
int (*table)[N] = new int[N][N];
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
table[i][j] = i*j;
return table;
}
#include <iostream>
int main()
{
int (*t)[N] = tableCreator();
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
std::cout << t[i][j] << ' ';
std::cout << '\n';
}
delete [] t;
return 0;
}
I. Arrays are not pointers.
II. Why not vector<vector<int> >?
III. If not, then:
typedef int Int10Array[10];
Int10Array *arr = new Int10Array[10];
IV. Why write past the bounds? Do you want explicit nasal demons?
for(int xxx = 0; xxx < 10; xxx++)
^^^ ^^^^