2d arrays issue connected with passing a filled array - c++

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.

Related

How to create a 2D array using a function?

I am trying to define a 2D array, but I want to do it in a function,
here is my code:
int** createArray( int columns, int rows)
{
int** array[rows];
for(int i = 0; i < rows; i++)
{
array[i] = new int*[columns];
}
for(int i = 0; i <columns; i++)
{
for(int j = 0; j < rows; j++)
{
array[i][j] = 0;
std::cout <<array[i][j];
}
std::cout<<"\n";
}
return *array;
}
int main()
{
int **myArray = createArray(3,5);
for(int k =0; k < 5; k++)
{
if( (myArray[0][k] == 0) && (&myArray[1][k] == 0)) //segmentation fault
{
myArray[2][k] = 10; //segmentation fault
}
delete[] myArray;
}
But it causes errors which can be seen as comments in lines. I am new to C++ and I do not know how to fix this.
Thank you very much
Prefer std::vector over manual memory management:
std::vector<std::vector<int>> createArray(int columns, int rows)
{
return std::vector<std::vector<int>(rows, std::vector<int>(columns));
}
int main()
{
int COLUMNS = 5;
int ROWS = 3;
auto myArray= createArray(COLUMNS, ROWS);
/*
Do stuff
*/
//std::vector handles delete on it's own, no need to clean up
}
If you cannot use std::vector for some reason, this is the a way to initialize 2D array on the heap:
int** createArray(int columns, int rows)
{
int** arr = new int*[rows];
for(int i = 0; i < rows; ++i)
{
arr[i] = new int[columns];
}
return arr;
}
int main()
{
int COLUMNS = 5;
int ROWS = 3;
int** myArray= createArray(COLUMNS, ROWS);
/*
Do stuff
*/
//you need to a delete for every new and delete[] for every new[]
for(int i = 0; i < rows; ++i)
{
delete[] myArray[i];
}
delete[] myArray;
}

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

function to double size of array arbitrary number of times?

I am trying to get this function to create anew array to be 2x the size of the array argument, copy the contents into the new array, and for the second half of the array, create new values by doing 2*the values in the first half of the array, then delete the original array. Repeat this process for the specified number of times, then return the new array. I feel like I have the right algorithm down but my code isn't working. Please help!
int *ArrayDynamicAllocation(int array[], int size, int number)
{
int *new_array = NULL;
for(int i=0; i<number-1; i++)
{
new_array = new int[size*2];
for(int j=0; j<size-1; j++)
{
new_array[j]=array[j];
new_array[j+size]=2*array[j];
}
array=new_array;
delete[] array;
size=size*2;
}
return new_array;
}
An example output would be if my info to put into my function was
int arr[2] = {0,1};
array_size = 2;
number = 3;
I want it to output 0 1 0 2 0 2 0 4 0 2 0 4 0 4 0 8
int *ArrayDynamicAllocation(int array[], int size, int number)
{
int *new_array = NULL;
int *tmp_array = new int[array.length()];
for(int k=0; k<array.length(); k++)//Initial array copying.
tmp_array[k] = array[k];
for(int i=0; i<number; i++)//Array range 0 to n-1
{
new_array = new int[size*2];
for(int j=0; j<size; j++)//Array range 0 to n-1
{
new_array[j]=tmp_array[j];
new_array[j+size]=2*tmp_array[j];
}
delete[] tmp_array //Deleting old array
size=size*2;
tmp_array = new int[size] //Allocating memory for next iteration
for(int k=0; k<size; k++)
tmp_array[k] = new_array[k];//Copying array for next iteration
}
delete[] tmp_array;// To free memory
return new_array;
};
c array range from 0 to size-1
change
for(int i=0; i<number-1; i++)
to
for(int i=0; i<=number-1; i++)
change
for(int j=0; j<size-1; j++)
to
for(int j=0; j<=size-1; j++)
you are deleting wrong array
change
array=new_array;
delete[] array;
to
delete[] array;
array=new_array;
template<class T>
void changeSize1d(T*&a, const int oldSize, const int newSize){
if(newSize<0)return 0;
T*temp new T[newSize];
int number = min(oldSize, newSize);
copy(a, a+number, temp);
delete [] a;
a = temp;
}

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

Converting 2D vector to 2D array

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