In C++ you can initialize a one dimensional array with 0 with a code like this:
int myarray[100] = {0};
Is there a similar way for multidimensional arrays? Or am i forced to initialize it manually with for loops?
You do it exactly the same way
int marr[10][10] = {0};
Edit:
This is a C solution. For a C++ solution you can go for:
int marr[10][10] = {};
These 2 solutions do not work for arrays that have size defined via variables. e.g.:
int i, j = 10;
int marr[i][j];
To initialize such an array in C++ use std::fill.
A multidimensional array is an array of arrays.
The same general array initialization syntax applies.
By the way you can just write {}, no need to put an explicit 0 in there.
use vector instead of array it will give you more flexibility in declaration and in any other operation
vector<vector<int> > myarray(rows,vector<int>(columns, initial_value));
you can access them same as you access array,
and if u still want to use array then use std::fill
You could use std::memset to initialize all the elements of a 2D array like this:
int arr[100][100]
memset( arr, 0, sizeof(arr) )
Even if you have defined the size via variables this can be used:
int i=100, j=100;
int arr[i][j]
memset( arr, 0, sizeof(arr) )
This way all the elements of arr will be set to 0.
Using 2 vector containers:
std::vector<std::vector<int>> output(m, std::vector<int>(n, 0));
This way one can declare a 2D vector output of size (m*n) with all elements of the vector initialized to 0.
For "proper" multi-dimensional arrays (think numpy ndarray), there are several libraries available, for example Boost Multiarray. To quote the example:
#include "boost/multi_array.hpp"
#include <cassert>
int
main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
See also: High-performance C++ multi-dimensional arrays
In C++, simply you can also do this way:-
int x = 10, y= 10; int matrix[x][y] = {};
and then the 2d-array will be initialized with all zeroes.
Related
This question already has answers here:
how to use memset for double dimentional array?
(2 answers)
Closed 9 years ago.
What is the fastest way to set a 2-dim array of double,such as double x[N][N] all to -1?
I tried to use memset, but failed. Any good idea?
Use: std::fill_n from algorithm
std::fill_n(*array, sizeof(array) / sizeof (**array), -1 );
Example:
double array[10][10];
std::fill_n( *array, sizeof(array) / sizeof (**array), -1.0 );
//Display Matrix
for(auto i=0;i<10;i++)
{
for(auto j=0;j<10;j++)
cout<<array[i][j]<< " ";
cout<<endl;
}
A simple loop:
#include <stdio.h>
int main(void)
{
#define N 5
double x[N][N];
size_t i, n = sizeof(x) / sizeof(double);
for (i = 0; i < n; i++)
x[0][i] = -1.0;
for (i = 0; i < n; i++)
printf("%zu) %f\n", i, x[0][i]);
}
// create constants
const int rows = 10;
const int columns = 10;
// declare a 2D array
double myArray [rows][columns];
// run a double loop to fill up the array
for (int i = 0; i < rows; i++)
for (int k = 0; k < columns; k++)
myArray[rows][columns] = -1.0;
// print out the results
for (int i = 0; i < rows; i++) {
for (int k = 0; k < columns; k++)
cout << myArray[rows][columns];
cout << endl;
}
Also you can set directly
double x[4][4] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
if the array index is small.
Using std::array and its fill method:
#include <array>
#include <iostream>
int main()
{
const std::size_t N=4
std::array<double, N*N> arr; // better to keep the memory 1D and access 2D!
arr.fill(-1.);
for(auto element : arr)
std::cout << element << '\n';
}
Using C++ containers you can use the fill method
array<array<double, 1024>, 1024> matrix;
matrix.fill(-1.0);
if, for some reason, you have to stick with C-style arrays you can initialize the first row manually and then memcpy to the other rows. This works regardless if you have defined it as static array or allocated row by row.
const int rows = 1024;
const int cols = 1024;
double matrix[rows][cols]
for ( int i=0; i<cols; ++i)
{
matrix[0][cols] = -1.0;
}
for ( int r=1; r<rows; ++r)
{
// use the previous row as source to have it cache friendly for large matrices
memcpy(&(void*)(matrix[row][0]), &(void*)(matrix[row-1][0]), cols*sizeof(double));
}
But I rather would try to move from C style arrays to the C++ containers than doing that kind of stunt.
memset shouldn't be used here because it is based on void *. So all bytes in are the same. (float) -1 is 0xbf800000 (double 0xbff0000000000000) so not all bytes are the same...
I would use manual filling:
const int m = 1024;
const int n = 1024;
double arr[m][n];
for (size_t i = 0; i < m*n; i++)
arr[i] = -1;
Matrix is like array in memory, so better to have 1 loop, it slightly faster.
Or you can use this:
std::fill_n(arr, m*n, -1);
Not sure which one is faster, but both looks similar. So probably you'll need to make small test to find it out, but as far as I know people usually use one or another. And another thing first one is more C on some compiler it won't work and second is real C++ it and never works on C. So you should choose by the programming language I think :)
I was wondering if there is a clever way of presenting the information in a vector as a 1D array. Example:
Let's create a vector of vectors of 5x3 int elements
vector< vector<int>> iVector;
ivector.resize( 5 );
for(i = 0; i < 5; i++){
iVector[i].resize(3);
}
But now I want this structure to be converted into a 1D array:
int* myArray = new int[5*3];
So I could access each element which I want as follows:
for (i =0;i < 5; i++)
for(j =0; j< 3; j++)
myArray[i*3+j] = ...
I know I could just copy the vector to the array element by element, but I was wondering if there is a method that directly addresses the vector to array conversion. I also know that the vector can me addressed as iVector[i][j] , but unfortunately it needs to be an array as it will be sent to a GPU and GPUs dont understand vectors.
Just use std::copy 5 times.
int* ptrArray = myArray;
for (i =0;i < 5; i++) {
std::copy(iVector[i].begin(), iVector[i].end(), ptrArray);
ptrArray += iVector[i].size();
}
There's really nothing you can do here except copy it into an array. The GPU will not understand any abstraction you create any more than it can understand std::vector. All you can do is make an array and copy it over.
Vectors supposed to store the elements in a linear fashion, so in theory you can refer to the entire underlying vector (only a single vector):
std::vector<int> numbers;
int data[4] = &(numbers[0]);
Similarily, perhaps you can try the same approach for the 2D version.
However in your place I would consider to use a class that is specifically designed to handle matrices (it is easy to write one similar to std::vector().
Or you can use plain old C.
You first initialize the array size to be the number of rows * the number of columns your vector of vectors has. Then you use memcpy to copy each vector to the array.
vector<vector<int> > v = { {1,2},{3,4},{5,6} }; //v is 3 by 2 matrix
int *arr = (int*)malloc( (3*2) * sizeof(int)); // arr has size 3*2 = 6
for (int i = 0; i < 3; i++)
memcpy(arr + v[i].size() * i, &(v[i][0]), v[i].size() * sizeof(int));
Here's a function that I wrote that does this for you:
template<typename T>
T *vectorToArray(vector<vector<T> > const &v) {
T *rv = (T*)malloc((v.size()*v[0].size()) * sizeof(T)); //Assuming all rows have the same size
for (unsigned i = 0; i < v.size(); i++)
memcpy(rv + v[i].size() * i, &(v[i][0]), v[i].size() * sizeof(T));
return rv;
}
So now you can do something like this:
vector<vector<int> > v = { {1,2},{3,4},{5,6} }; //v is 3 by 2 matrix
int *arr = vectorToArray(v);
I hope this helps
I would like to get a two dimensional int array arr that I can access via arr[i][j].
As far as I understand I could declare int arr[10][15]; to get such an array.
In my case the size is however variable and as far as I understand this syntax doesn't work if the size of the array isn't hardcoded but I use a variable like int arr[sizeX][sizeY].
What's the best workaround?
If you don't want to use a std::vector of vectors (or the new C++11 std::array) then you have to allocate all sub-arrays manually:
int **arr = new int* [sizeX];
for (int i = 0; i < sizeX; i++)
arr[i] = new int[sizeY];
And of course don't forget to delete[] all when done.
c/c++ does not support multidimensional array. But it does support array of array:
//simulate 2-dimension array with 1-dimension array
{
int x = 20;
int y = 40;
int * ar = new int(x*y);
int idx_x =9;
int idx_y=12;
ar[idx_x + idx_y * x] = 23;
}
//simulate 2-dimension array with array of array
{
int x = 20;
int y = 40;
int**ar = new int*[y];
for(int i = 0; i< y; ++i)
{
ar[i] = new int[x];
}
ar[9][12] = 0;
}
If you're looking for the solution in C, see this Stack Overflow thread:
How do I work with dynamic multi-dimensional arrays in C?.
If C++ is okay, then you can create a 2D vector, i.e. a vector of vectors. See http://www.cplusplus.com/forum/general/833/.
You can't, with array syntax. The language requires that you use compile time constants to create arrays.
C++ does not have variable length arrays. You can consider using vector<vector<int> >. It can be also accessed using arr[i][j].
As fefe said you can use vector of vectors, e. g. :
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector< vector<int> > vec;
vector<int> row1;
row1.push_back(1);
row1.push_back(2);
vector<int> row2;
row2.push_back(3);
row2.push_back(4);
vec.push_back(row1);
vec.push_back(row2);
for( int ix = 0; ix < 2; ++ix)
for( int jx = 0; jx < 2; ++jx)
cout << "[" << ix << ", " << jx << "] = " << vec[ix][jx] << endl;
}
I need help in using the boost multidimensional array. I have to construct a two dimensional array where: (0 <= j <= 1) and (i) grows dynamically according to:
long boostArray[i][j];
Thus, It's like constructing a table of (unknown) columns and two rows.
I started already with the example provided at the Boost Library website:
#include "boost/multi_array.hpp"
#include <cassert>
int main () {
// 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
The problem is that i didn't thoroughly understand the above code in order to tweak on its structure and build up my desired array. I don't know precisely how to add/delete elements to/from my array while using the Boost Library especially if this array grows dynamically as i described above.
For example, when dealing with vectors, i tend to use: push_back and pop_back after resizing the vector.
For your particular usecase, you're probably better off using vector<pair<T,T>> or vector<array<T,2>>. You can then use push_back, and it's efficient. boost::multi_array sounds like overkill, otoh:
You can't use something like push_back there, because whenever you extend one dimension of an N-dimensional array, you'd need to supply a slice of N-1 dimensions of initial data. That is usually not very efficient, esp. since you can only add to the dimension with the largest stride in this way. What you need to use instead is resize and assignment.
// std::vector<> equivalent (with vector<>, it's considered bad style)
v.resize( v.size() + 1 );
v[v.size()-1] = newElement;
// boost::multi_array (from the tutorial)
typedef boost::multi_array<int, 3> array_type;
array_type::extent_gen extents;
array_type A(extents[3][3][3]);
A[0][0][0] = 4;
A[2][2][2] = 5;
// here, it's the only way:
A.resize(extents[2][3][4]);
assert(A[0][0][0] == 4);
// A[2][2][2] is no longer valid.
To reiterate: N-dimensional arrays, N>2, are inherently much less dynamic than one-dimensional ones (because of the stride factor). The above resize requires a lot of copying of the data, unlike the vector case, which only needs to copy data when size()>capacity().
How do you initialize and Uninitialize a multidimensional character array in C++?
Read the FAQ -- you'll find everything you need there!
Creation:
Statically allocated:
char mda[ dim1_size ][ dim2_size ]...[ dimn_size ];
Dynamically allocated: Nested new[] calls.
Initialization:
Nested for loops; as many for as your dimensions.
Unitialization: Do you mean Destruction?
Statically allocated: The compiler does this when the stack frame is unwound (or for global variables -- when the program stops running).
Dynamically allocated:
Using nested delete[].
I suggest you use the Boost.Multi_Array library.
The dimension of the array has to be provided at compile-time, but the sizes are only used at runtime.
That means that you have the advantages of dynamic allocation without the pain of having to deal with memory issues.
Here goes the example from the Boost documentation.
int
main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
This is interesting, and this requires a serious look.
The answer given by roo is a widely used one, but I like his observation - just because it compiles doesn't mean it works
I would think a better solution would be to allocate a contigious block of memory (rows * cols) long and then treat it as a 2D array?
you can initialize a multidimensional array like this:
int grid[2][3] = {1, 3, 5, 2, 4, 6};
in that case the seperate values would be:
grid[0, 0]: 1
grid[0, 1]: 3
grid[0, 2]: 5
grid[1, 0]: 2
grid[1, 1]: 4
grid[1, 2]: 6
A quick snippet - it compiles in g++.
int rows = 10;
int cols = 10;
char** array = new char*[rows];
for( int i = 0; i < cols; ++i ) {
array[i] = new char[cols];
}
//do stuff with array
for( int i = 0; i < cols; ++i ) {
delete array[i];
}
delete array;
I learned it with a tic tac toe board
const int ROW = 3;
const int COLUMN = 3;
char board [ROW] [COLUMN] = {{'O', 'X', 'O'},
{'X', 'X', 'X'},
{'X', 'O', 'X'}};
I hope this helped.