How to heap allocate a 2D array in C++? [duplicate] - c++

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 5 years ago.
I am trying to do something like this:
std::string* Plane = new std::string[15][60];
However this code seems not to compile.
Is there any other way to accomplish the same result?
Thanks for any potential help.

There's three ways of doing this.
The first is to allocate it as an 'array of arrays' structure (I'm converting your code to std::vector, because it's way safer than dealing with raw pointers). This is ideal if you need each row to have its own length, but eats up extra memory:
std::vector<std::vector<std::string>> Plane(15);
for(size_t index = 0; index < 15; index++)
Plane[index].resize(60);
for(size_t i = 0; i < 15; i++)
for(size_t j = 0; j < 60; j++)
Plane[i][j] = "This is a String!";
The second is to allocate it as a flat structure, which dramatically improves performance at the cost of reduction of flexibility:
std::vector<std::string> Plane(15 * 60);
for(size_t i = 0; i < 15; i++)
for(size_t j = 0; j < 60; j++)
Plane[i* 60 + j] = "This is a String!";
The third, which I consider the best option by far because of its extensibility, is to roll a Matrix class which abstracts away these details for you, making it less likely you'll make a mistake in your coding:
template<typename T>
class Matrix {
std::vector<T> _data;
size_t rows, columns;
public:
Matrix(size_t rows, size_t columns) : rows(rows), columns(columns), _data(rows * columns) {}
T & operator()(size_t row, size_t column) {
return _data[row * columns + column];
}
T const& operator()(size_t row, size_t column) const {
return _data[row * columns + column];
}
};
Matrix<std::string> Plane(15, 60);
for(size_t i = 0; i < 15; i++)
for(size_t j = 0; j < 60; j++)
Plane(i, j) = "This is a String!";
Of course, that's an extremely simplified implementation; you'd probably want to add a bunch of STL-like functionality like rows(), columns(), at(), begin(), end(), etc.

When using new[] to allocate a multi-dimensional array, you have to allocate each dimension separately, eg:
std::string** Plane = new std::string*[15];
for(int i = 0; i < 15; ++i)
Plane[i] = new std::string[60];
...
for(int i = 0; i < 15; ++i)
delete[] Plane[i];
delete[] Plane;
To access a string at a given row/column pair, you can using Planes[row][column] syntax.
Otherwise, flatten it into a 1-dimensional array instead:
std::string* Plane = new std::string[15*60];
...
delete[] Plane;
To access a string at a given row/column pair, you can using Planes[(row*60)+column] syntax.
That being said, you should stay away from using raw pointers like this. Use std::vector or std::array instead:
typedef std::vector<std::string> string_vec;
// or, in C++11 and later:
// using string_vec = std::vector<std::string>;
std::vector<string_vec> Planes(15, string_vec(60));
// C++11 and later only...
std::vector<std::array<std::string, 60>> Planes(15);
// C++11 and later only...
using Plane_60 = std::array<std::string, 60>;
std::unique_ptr<Plane_60[]> Planes(new Plane_60[15]);
// C++14 and later only..
using Plane_60 = std::array<std::string, 60>;
std::unique_ptr<Plane_60[]> Planes = std::make_unique<Plane_60[]>(15);
Any of these will let you access strings using Planes[row][column] syntax, while managing the array memory for you.

Related

2D complex array in C++

I am new in C++ programing so I need a help about 2D arrays. Is it possible to create complex array from two real array with two for loops?I was trying to do that in my code but...I do not know how to do that.
Thanks for help!
This is my code::
#include <iostream>
#include <fstream>
#include <complex>
#include <cmath>
using namespace std;
int const BrGr = 15, BrCv = BrGr + 1, BrSat = 24;
//(BrCv=number of nodes,BrSat=number of hours)
int main()
{
// Every array must be dynamic array.It is a task.Is this correct way?
auto *Ipot = new double[BrCv - 1][BrSat];
auto *cosfi = new double[BrCv - 1][BrSat];
auto *S_pot = new complex<double>[BrCv - 1][BrSat];
auto *I_inj = new complex<double>[BrCv - 1][BrSat];
auto *V_cvo = new complex<double>[BrCv][BrSat];
ifstream reader("Input.txt");
if (reader.is_open())
{
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
reader >> Ipot[i][j];
}
}
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
reader >> cosfi[i][j];
}
}
}
else cout << "Error!" << endl;
reader.close();
// Here i want to create 2D array of complex numbers - Is this correct way?
// Also in same proces i want to calculate a value of S_pot in every node for every hour
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
S_pot[i][j] = complex<double>(Ipot[i][j]*cosfi[i][j],Ipot[i][j]*sqr(1-pow(cosfi[i][j],2)));
}
}
// Here i give a value for V_cvo in nodes for every single hour
for (int i = 0;i < BrCv;i++)
{
for (int j = 0;j < BrSat;j++)
{
V_cvo[i][j] = 1;
}
}
// Here i want to calculate a value of I_inj in every node for every hour
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
I_inj[i][j] = conj(S_pot[i][j] / V_cvo[i][j]);
}
}
// Here i want to delete all arrays
delete[] Ipot, cosfi, S_pot, I_inj, V_cvo;
system("pause");
return 0;
Note: I'm using double through out these examples, but you can replace double with any type.
To be honest, you probably don't want to use a 2D array.
Creating a 2D dynamically-sized array in C++ is a multi-stage operation. You can't just
double twoDArray [nrRows][nrColumns];
or
auto twoDArray = new double[nrRows][nrColumns];
There are a couple things wrong with this, but the most important is the rows and columns are not a constant, defined at compile time values. Some compilers allow the first, but this cannot be guaranteed. I don't know if any compiler allows the second.
Instead, First you create an array of rows to hold the columns, then you separately create each row of columns. Yuck.
Here's the set up:
double * arr[] = new double*[nrRows]; // create rows to point at columns
for (size_t index = 0; index < nrRows; index++)
{
arr[index] = new double[nrColumns]; // create columns
}
And here's clean-up
for (size_t index = 0; index < nrRows; index++)
{
delete[] arr[index]; // delete all columns
}
delete[] arr; // delete rows
For your efforts you get crappy spacial locality and the performance hit (Cache miss) that causes because your many arrays could be anywhere in RAM, and you get crappy memory management issues. One screw-up, one unexpected exception and you have a memory leak.
This next option has better locality because there is one big data array to read from instead of many, but still the same leakage problems.
double * arr2[] = new double*[nrRows]; // create rows to point at columns
double holder[] = new double[nrRows* nrColumns]; // create all columns at once
for (size_t index = 0; index < nrRows; index++)
{
arr[index] = &holder[index * nrColumns]; // attach columns to rows
}
and clean up:
delete[] arr2;
delete[] holder;
In C++, the sane person chooses std::vector over a dynamically-sized array unless given very, very compelling reason not to. Why has been documented to death all over SO and the Internet at large, and the proof litters the Internet with hijacked computers serving up heaping dollops of spam and other nastiness.
std::vector<std::vector<double>> vec(nrRows, std::vector<double>(nrColumns));
Usage is exactly what array users are used to:
vec[i][j] = somevalue;
This has effectively no memory problems, but is back to crappy locality because the vectors could be anywhere.
But...!
There is a better method still: Use a One Dimensional array and wrap it in a simple class to make it look 2D.
template <class TYPE>
class TwoDee
{
private:
size_t mNrRows;
size_t mNrColumns;
vector<TYPE> vec;
public:
TwoDee(size_t nrRows, size_t nrColumns):
mNrRows(nrRows), mNrColumns(nrColumns), vec(mNrRows*mNrColumns)
{
}
TYPE & operator()(size_t row, size_t column)
{
return vec[row* mNrColumns + column];
}
TYPE operator()(size_t row, size_t column) const
{
return vec[row* mNrColumns + column];
}
};
This little beastie will do most of what you need a 2D vector to do. You can copy it, you can move it. You can crunch all you want. Jay Leno will make more.
I jumped directly to the templated version because I'm stumped for a good reason to explain class TwoDee twice.
The constructor is simple. You give it the dimensions of the array and it builds a nice, safe 1D vector. No muss, no fuss, and No Zayn required.
The operator() functions take the row and column indices, do a simple bit of arithmetic to turn the indices into a single index and then either return a reference to the indexed value to allow modification or a copy of the indexed value for the constant case.
If you're feeling like you need extra safety, add in range checking.
TYPE & operator()(size_t row, size_t column)
{
if (row < mNrRows && column < mNrColumns)
{
return vec[row* mNrColumns + column];
}
throw std::out_of_range("Bad indices");
}
OK. How does the OP use this?
TwoDee<complex<double>> spot(BrCv - 1, BrSat);
Created and ready to go. And to load it up:
for (int i = 0;i < BrCv - 1;i++)
{
for (int j = 0;j < BrSat;j++)
{
Spot(i,j) = complex<double>(7.8*Ipot(i,j),2.3*cosfi(i,j));
}
}
Declaring a dynamic 2D array for a premitive type is the same as for std::complex<T>.
Jagged array:
complex<int> **ary = new complex<int>*[sizeY];
//run loop to initialize
for (int i = 0; i < sizeY; ++i)
{
ary[i] = new complex<int>[sizeX];
}
//clean up (you could wrap this in a class and write this in its destructor)
for (int i = 0; i < sizeY; ++i)
{
delete[] ary[i];
}
delete[] ary;
//access with
ary[i][j];
//assign index with
ary[i][j] = complex<int>(int,int);
It's a little heavier weight than it needs to be, and it allocates more blocks than you need.
Multidimensional arrays only need one block of memory, they don't need one block per row.
Rectangular array:
complex<int> *ary = new complex<int>[sizeX * sizeY];
//access with:
ary[y*sizeX + x]
//assign with
ary[y*sizeX+x] = complex<int>(int,int);
//clean up
delete[] ary;
Allocating just a single contiguous block is the way to go (less impact on allocator, better locality, etc But you have to sacrifice clean and nice subscripting.

slow performance for 3D array delete C++

int newHeight = _height/2;
int newWidth = _width/2;
double*** imageData = new double**[newHeight];
for (int i = 0; i < newHeight; i++)
{
imageData[i] = new double*[newWidth];
for (int j = 0; j < newWidth; j++)
{
imageData[i][j] = new double[4];
}
}
I have dynamically allocated this 3D matrix.
what is the fastest and safest way to free the memory here?
here is that I have done but this takes a few seconds my matrix is big (1500,2000,4)
for (int i = 0; i != _height/2; i++)
{
for (int j = 0; j != _width/2; j++)
{
delete[] imageData[i][j];
}
delete[] imageData[i];
}
delete[] imageData;
Update
As suggested I have chosen this solution:
std::vector<std::vector<std::array<double,4>>>
the performance is great for my case
Allocate the entire image data as one block so you can free it as one block, ie. double* imageData = new double[width*height*4]; delete [] imageData; and index into it using offsets. Right now you are making 3 million separate allocations which is thrashing your heap.
I agree with qartar's answer right up until he said "index into it using offsets". That isn't necessary. You can have your single allocation and multiple subscript access (imageData[i][j][k]) too. I previously showed this method here, it's not difficult to adapt it for the 3-D case:
allocation code as follows:
double*** imageData;
imageData = new double**[width];
imageData[0] = new double*[width * height];
imageData[0][0] = new double[width * height * 4];
for (int i = 0; i < width; i++) {
if (i > 0) {
imageData[i] = imageData[i-1] + height;
imageData[i][0] = imageData[i-1][0] + height * 4;
}
for (int j = 1; j < height; j++) {
imageData[i][j] = imageData[i][j-1] + 4;
}
}
Deallocation becomes simpler:
delete[] imageData[0][0];
delete[] imageData[0];
delete[] imageData;
Of course, you can and should use std::vector to do the deallocation automatically:
std::vector<double**> imageData(width);
std::vector<double*> imageDataRows(width * height);
std::vector<double> imageDataCells(width * height * 4);
for (int i = 0; i < width; i++) {
imageData[i] = &imageDataRows[i * height];
for (int j = 0; j < height; j++) {
imageData[i][j] = &imageDataCells[(i * height + j) * 4];
}
}
and deallocation is completely automatic.
See my other answer for more explanation.
Or use std::array<double,4> for the last subscript, and use 2-D dynamic allocation via this method.
A slight variation on the first idea of Ben Voigt's answer:
double ***imagedata = new double**[height];
double **p = new double*[height * width];
double *q = new double[height * width * length];
for (int i = 0; i < height; ++i, p += width) {
imagedata[i] = p;
for (int j = 0; j < width; ++j, q += length) {
imagedata[i][j] = q;
}
}
// ...
delete[] imagedata[0][0];
delete[] imagedata[0];
delete[] imagedata;
It is possible to do the whole thing with a single allocation, but that would introduce a bit of complexity that you might not want to pay.
Now, the fact that each table lookup involves a couple of back-to-back reads of pointers from memory, this solution will pretty much always be quite inferior to allocating a flat array, and doing index calculations to convert a triple of indices into one flat index (and you should write a wrapper class that does these index calculations for you).
The main reason to use arrays of pointers to arrays of pointers to arrays is when your array is ragged — that is, imagedata[a][b] and imagedata[c][d] have different lengths — or maybe for swapping rows around, such as swap(imagedata[a][b], imagedata[c][d]). And under these circumstances, vector as you've used it is preferable to use until proven otherwise.
The primary portion of your algorithm that is killing performance is the granularity and sheer number of allocations you're making. In total you're producing 3001501 broken down as:
1 allocation for 1500 double**
1500 allocations, each of which obtains 2000 double*
3000000 allocations each of which obtains double[4]
This can be considerably reduced. You can certainly do as other suggest and simply allocate 1 massive array of double, leaving the index calculation to accessor functions. Of course, if you do that you need to ensure you bring the sizes along for the ride. The result, however, will easily deliver the fastest allocation time and access performance. Using a std::vector<double> arr(d1*d2*4); and doing the offset math as needed will serve very well.
Another Way
If you are dead set on using a pointer array approach, you can eliminate the 3000000 allocations by obtaining both of the inferior dimensions in single allocations. Your most-inferior dimension is fixed (4), thus you could do this: (but you'll see in a moment there is a much more C++-centric mechanism):
double (**allocPtrsN(size_t d1, size_t d2))[4]
{
typedef double (*Row)[4];
Row *res = new Row[d1];
for (size_t i=0; i<d1; ++i)
res[i] = new T[d2][4];
return res;
}
and simply invoke as:
double (**arr3D)[4] = allocPtrsN(d1,d2);
where d1 and d2 are your two superior dimensions. This produces exactly d1 + 1 allocations, the first being d1 pointers, the remaining be d1 allocations, one for each double[d2][4].
Using C++ Standard Containers
The prior code is obviously tedious, and frankly prone to considerable error. C++ offers a tidy solution this using a vector of vector of fixed array, doing this:
std::vector<std::vector<std::array<double,4>>> arr(1500, std::vector<std::array<double,4>>(2000));
Ultimately this will do nearly the same allocation technique as the rather obtuse code shown earlier, but provide you all the lovely benefits of the standard library while doing it. You get all those handy members of the std::vector and std::array templates, and RAII features as an added bonus.
However, this is one significant difference. The raw pointer method shown earlier will not value-initialize each allocated entity; the vector of vector of array method will. If you think it doesn't make a difference...
#include <iostream>
#include <vector>
#include <array>
#include <chrono>
using Quad = std::array<double, 4>;
using Table = std::vector<Quad>;
using Cube = std::vector<Table>;
Cube allocCube(size_t d1, size_t d2)
{
return Cube(d1, Table(d2));
}
double ***allocPtrs(size_t d1, size_t d2)
{
double*** ptrs = new double**[d1];
for (size_t i = 0; i < d1; i++)
{
ptrs[i] = new double*[d2];
for (size_t j = 0; j < d2; j++)
{
ptrs[i][j] = new double[4];
}
}
return ptrs;
}
void freePtrs(double***& ptrs, size_t d1, size_t d2)
{
for (size_t i=0; i<d1; ++i)
{
for (size_t j=0; j<d2; ++j)
delete [] ptrs[i][j];
delete [] ptrs[i];
}
delete [] ptrs;
ptrs = nullptr;
}
double (**allocPtrsN(size_t d1, size_t d2))[4]
{
typedef double (*Row)[4];
Row *res = new Row[d1];
for (size_t i=0; i<d1; ++i)
res[i] = new double[d2][4];
return res;
}
void freePtrsN(double (**p)[4], size_t d1, size_t d2)
{
for (size_t i=0; i<d1; ++i)
delete [] p[i];
delete [] p;
}
std::vector<std::vector<std::array<double,4>>> arr(1500, std::vector<std::array<double,4>>(2000));
template<class C>
void print_duration(const std::chrono::time_point<C>& beg,
const std::chrono::time_point<C>& end)
{
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count() << "ms\n";
}
int main()
{
using namespace std::chrono;
time_point<system_clock> tp;
volatile double vd;
static constexpr size_t d1 = 1500, d2 = 2000;
tp = system_clock::now();
for (int i=0; i<10; ++i)
{
double ***cube = allocPtrs(d1,d2);
cube[d1/2][d2/21][1] = 1.0;
vd = cube[d1/2][d2/2][3];
freePtrs(cube, 1500, 2000);
}
print_duration(tp, system_clock::now());
tp = system_clock::now();
for (int i=0; i<10; ++i)
{
Cube cube = allocCube(1500,2000);
cube[d1/2][d2/21][1] = 1.0;
vd = cube[d1/2][d2/2][3];
}
print_duration(tp, system_clock::now());
tp = system_clock::now();
for (int i=0; i<10; ++i)
{
auto cube = allocPtrsN(d1,d2);
cube[d1/2][d2/21][1] = 1.0;
vd = cube[d1/2][d2/21][1];
freePtrsN(cube, d1, d2);
}
print_duration(tp, system_clock::now());
}
Output
5328ms
418ms
95ms
Thusly, if you're planning on loading up every element with something besides zero anyway, it is something to keep in mind.
Conclusion
If performance were critical I would use the 24MB (on my implementation, anyway) single-allocation, likely in a std::vector<double> arr(d1*d2*4);, and do the offset calculations as needed using one form of secondary indexing or another. Other answers proffer up interesting ideas on this, notably Ben's, which radically reduces the allocation count two a mere three blocks (data, and two secondary pointer arrays). Sorry, I didn't have time to bench it, but I would suspect the performance would be stellar. But if you really want to keep your existing technique, consider doing it in a C++ container as shown above. If the extra cycles spent value initializing the world aren't too heavy a price to pay, it will be much easier to manage (and obviously less code to deal with in comparison to raw pointers).
Best of luck.

How to create a two dimensional array of given size in C++

I need to create a square matrix of a given size. I know how to create a dynamic one-dimensional array of a given size. Doesn't the same work for two dimensinal arrays like the lines below?
cin>>size;
int* a[][]=new int[size][size]
int* a[][]=new int[size][size]
No, this doesn't work.
main.cpp:4: error: only the first dimension of an allocated array may have dynamic size
new int[size][size];
^~~~
If the size of the rows were fixed then you could do:
// allocate an array with `size` rows and 10 columns
int (*array)[10] = new int[size][10];
In C++ you can't have raw arrays with two dimensions where both dimensions are dynamic. This is because raw array indexing works in terms of pointers; for example, in order to access the second row a pointer to the first needs to be incremented by the size of the row. But when the size of a row is dynamic the array doesn't know that size and so C++ doesn't know how to figure out how to do the pointer increment.
If you want an array with multiple dynamic dimensions, then you need to either structure the array allocations such that C++'s default array indexing logic can handle it (such as the top answers to this duplicate question), or you need to implement the logic for figuring out the appropriate pointer increments yourself.
For an array where each row has the same size I would recommend against using multiple allocations such as those answers suggest, or using a vector of vectors. Using a vector of vectors addresses the difficulty and dangerousness of doing the allocations by hand, but it still uses more memory than necessary and doesn't allow faster memory access patterns.
A different approach, flattening the multi-dimensional array, can make for code as easy to read and write as any other approach, doesn't use extra memory, and can perform much, much better.
A flattened array means you use just a single dimentional array that has the same number of elements as your desired 2D array, and you perform arithmetic for converting between the multi-dimensional indices and the corresponding single dimensional index. With new it looks like:
int *arr = new int[row_count * column_count];
Row i, column j in the 2d array corresponds to arr[column_count*i + j]. arr[n] corresponds to the element at row n/column_count and column n% column_count. For example, in an array with 10 columns, row 0 column 0 corresponds to arr[0]; row 0, column 1 correponds to arr[1]; row 1 column 0 correponds to arr[10]; row 1, column 1 corresponds to arr[11].
You should avoid doing manual memory management using raw new and delete, such as in the case of int *arr = new int[size];. Instead resource management should be wrapped up inside a RAII class. One example of a RAII class for managing dynamically allocated memory is std::vector.
std::vector<int> arr(row_count * column_count);
arr[column_count*i + j]
You can further wrap the logic for computing indices up in another class:
#include <vector>
class Array2d {
std::vector<int> arr;
int columns;
public:
Array2d(int rows, int columns)
: arr(rows * columns)
, columns(columns)
{}
struct Array2dindex { int row; int column; };
int &operator[] (Array2dindex i) {
return arr[columns*i.row + i.column];
}
};
#include <iostream>
int main() {
int size;
std::cin >> size;
Array2d arr(size, size);
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
arr[{i, j}] = 100;
}
}
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
std::cout << arr[{i, j}] << ' ';
}
std::cout << '\n';
}
}
If you're using C++11 you can also use std::array.
const int iRows = 3, iCols = 3; // number of rows and columns
std::array<std::array<int, iCols>, iRows> matrix;
// fill with 1,2,3 4,5,6 7,8,9
for(int i=0;i<iRows;++i)
for(int j=0;j<iCols;++j)
matrix[i][j] = i * iCols + j + 1;
This class also allows for bounds checking by using the function
std::array::at
which (just like operator[]) returns a const reference if the array-object is const-qualified or a reference if it is not. Please note that
std::array
is not a variable-sized array-type, like
std::vector
You can use std::vector:
std::vector<std::vector<int*>> a(size, std::vector<int*>(size));
This will create a dynamically allocated 2D array of int* with width and height equal to size.
Or the same with new:
int*** a = new int**[size];
for (size_t i = 0; i < size; ++i)
a[i] = new int*[size];
...
for (size_t i = 0; i < size; ++i)
delete a[i];
delete a;
Note that there's no new[][] operator in C++, you just have to call new[] twice.
However, if you want to do it with new and delete instead of std::vector, you should use smart pointers instead of raw pointers, for example:
std::unique_ptr<std::unique_ptr<int*>[]> a(new std::unique_ptr<int*>[size]);
for (size_t i = 0; i < size; ++i)
a[i].reset(new int*[size]);
...
// No need to call `delete`, std::unique_ptr does it automatically.

Vector of vectors to 1D array

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

Best way to represent a 2-D array in C++ with size determined at run time

In C++ I'd like to do something like:
int n = get_int_from_user();
char* matrix = new char[n][n];
matrix[0][0] = 'c';
//...
matrix[n][n] = 'a';
delete [][] matrix;
but of course this doesn't work. What is the best way to do something similar? I've seen some solutions to this but they seem pretty messy.
The manual dynamic way:
Let's say you want an array of width*height, the most efficient way is to just use a single dimensional array:
char *matrix = new char[width*height];
To delete it:
delete[] matrix;
To access it:
char getArrayValue(char *matrix, int row, int col)
{
return matrix[row + col*width];
}
To modify it:
void setArrayValue(char *matrix, int row, int col, char val)
{
matrix[row + col*width] = val;
}
Boost Matrix:
Consider using boost::matrix if you can have the dependency.
You could then tie into the boost linear algebra libraries.
Here is some sample code of boost::matrix:
#include <boost/numeric/ublas/matrix.hpp>
using namespace boost::numeric::ublas;
matrix<char> m (3, 3);
for (unsigned i = 0; i < m.size1 (); ++ i)
for (unsigned j = 0; j < m.size2 (); ++ j)
m (i, j) = 3 * i + j;
On the stack for some compilers:
Some compilers actually allow you to create arrays on the stack with runtime determined sizes. g++ is an example of such a compiler. You cannot do this by default VC++ though.
So in g++ this is valid code:
int width = 10;
int height = 10;
int matrix[width][height];
Drew Hall mentioned that this C99 feature is called Variable Length Arrays (VLAs) and it can probably be turned on in any modern compiler.
I usually do something like this:
char *matrix = new char [width * height];
matrix[i + j * width] = 'c'; // same as matrix[i][j] = 'c';
delete [] matrix;
You seem to be missing the whole point of C++ (C with classes) :-). This is the sort of use that's crying out for a class to implement it.
You could just use STL or other 3rd party class library which I'm sure would have the data structure you're looking for but, if you need to roll your own, just create a class with the following properties.
constructor which, given n, will just create a new n*n array of char (e.g., charray)..
member functions which get and set values based on x.y which simply refer to charray[x*n+y];
destructor which delete[]'s the array.
What about std::vector< std::vector<int> > array2d; ?
For a true two dimensional array:
int n = get_int_from_user();
char** matrix = new char*[n];
for (int i = 0; i < n; i++) {
matrix[i] = new char[n];
}
// Operations on matrix.
for (int i = 0; i < n; i++) {
delete [] matrix[i];
}
delete matrix;
Just off the top of my head. Mistakes, no doubt. However, other people have posted a more elegant approach, I think.
I like the 1-d array approach (the selected answer by Brian R. Bondy) with the extension that you wrap the data members into a class so that you don't need to keep track of the width separately:
class Matrix
{
int width;
int height;
char* data;
public:
Matrix();
Matrix(int width, int height);
~Matrix();
char getArrayValue(int row, int col);
void setArrayValue(int row, int col, char val);
}
The implementation is an exercise for the reader. ;)
I think this would be a good one.
int n = get_int_from_user();
char **matrix=new (char*)[n];
for(int i=0;i<n;i++)
matrix[i]=new char[n];
matrix[0][0] = 'c';
//...
matrix[n][n] = 'a';
for(int i=0;i<n;i++)
delete []matrix;
delete []matrix;
std::vector<int> m;
Then call m.resize() at runtime.
int* matrix = new int[w*h];
if you want to do something like Gaussian elimination your matrix should be
int** matrix = new int*[h];
for(size_t i(0); i < h; ++i)
matrix[i] = new int[w];
(in Gaussian elimination we usually need to exchange one row with another so it's better to swap pointers to rows in constant time rather than swapping by copying in linear time).