C++ multidimensional dynamic array - c++

Let's say I have this to create a multidimensional array dynamically:
int* *grid = new int*[gridSizeX];
for (int i=0; i<gridSizeX; i++) {
grid[i] = new int[gridSizeY];
}
Shouldn't be possible now to access elements like grid[x][y] = 20?

Yes, this should work fine.
But... you might want to consider using standard containers instead of manually managing memory:
typedef std::vector<int> IntVec;
typedef std::vector<IntVec> IntGrid;
IntGrid grid(gridSizeX, IntVec(gridSizeY));
grid[0][0] = 20;

Yes - but in C/C++ it will be laid out as grid[y][x].

Related

Failed to allocate an array of pointers to a struct

I'm trying to allocate an array of pointers to a struct but there's something wrong with my code.
This is my struct:
struct Brick {
GameObject2D* handle_;
};
Brick** bricks_;
And this is how i'm trying to allocate memory for it:
int bricks_amount_ = 10;
bricks_ = (Brick**)malloc(sizeof(Brick*) * bricks_amount_);
The program crash. I've make a devenv on it to debug where's the problem and it crash on this line:
for (unsigned short int i = 0; i < bricks_amount_; i++){
bricks_[i]->handle_ = new GameObject2D(); <---------- CRASH!
}
Any suggestions?
PS: Sorry for my english :P
=========================================================================
[SOLUTION]
Finally i've decided to use std::vector instead raw pointers:
bricks_.resize(bricks_amount_);
but i've tried to make the malloc different way and it works too:
bricks_ = (struct Brick*)malloc(sizeof(struct Brick) * bricks_amount_);
or this:
bricks_ = new Brick[bricks_amount_];
Thank you to the people who wants to help!
It's C++:
don't use malloc, use new
don't use plain arrays, use std::vector or std::array
don't use raw pointers, use std::unique_ptr
Do not use
Bricks ** //will be a 2 dimensional array
Use instead
Bricks * //will be a 1 dimensioanal array
If you want a single dimensional array
Then do
`Bricks * bricks_ = (Bricks *)malloc(sizeof(Brick) * bricks_amount_ );
`
Then you can safely do without a crash
for (unsigned short int i = 0; i < bricks_amount_; i++){
bricks_[i]->handle_ = new GameObject2D(); <---------- There will not be CRASH!
}

Multidimensional array of struct - Segmentation fault

I have a pointer to array of structure and when I try to initialize it, I get a segmentation fault.
MyStruct **** node = NULL;
node[0][0][0] = new MyStruct();
I tried to use 2D array and it Works fine.
What is wrong?
Thanks for your replies.
You need to allocate memory before using it. You can't just jump 3 levels without allocating and use it.
Allocate node first. Then you can access node[0].
Now if you allocate node[0], you can access node[0][0].
Go on like this.
Try to dynamically allocate the array first, using the new operator:
MyStruct ****node = new MyStruct***[MAX_SIZE];
for(int i=0; i<MAX_SIZE; ++i) node[i] = new MyStruct**[MAX_SIZE];
for(int i=0; i<MAX_SIZE; ++i)
for(int j=0; j<MAX_SIZE; ++j) node[i][j] = new MyStruct*[MAX_SIZE];
node[0][0][0] = new MyStruct();

Reallocating 2D arrays on C++

lets say i have:
#include <iostream>
using namespace std;
int **a; //Global Variable
int main()
{
n=5;
a = new int*[n];
for ( int i = 0 ; i < n ; i++ )
a[i] = new int[n] ;
}
is there any realloc() method to increase the row size? (column size is fixed)
I mean if the row size is 5 then i wanna make it 6 not much more, just +1.
I use
for(i=0;i<n;i++)
{
counter++;
a[i] = (int *) realloc(a[i],counter*sizeof(int));
}
but i think something is wrong....
Edit: please don't advise any vector or sth like that.. Cuz i need my array as global.
realloc only works when you allocated with malloc. If you used new, you'll have to delete and then use new again (or just use something like a std::vector).
EDIT: Since you asked for an example of how to use malloc:
a = new int*[n];
would become
a = (int **) malloc (n * sizeof (int *));
and
a[i] = new int[n] ;
would become
a[i] = (int *) malloc (n * sizeof (int));
You can write your own routine to resize the array.
If you want a resized block with size N
allocate (new) the new size N
copy old array/block to this newly allocated array/block
free the old array (delete)
To avoid calling this routine again and again, better preallocate a large chunk, the size of chunk will be determined by the need of your application, and should be such which avoid resizing the array a lot of times.
The answer is No!
C++ memory management does not contain functionality for reallocating/resizing allocated memory. You would have to implement such a thing yourself using new/copy/delete semantics

Instantiating a std::vector of boost::multi_array.. melting brain for cpp guru?

I think I'm confused with instantiating objects.. well.. not properly object because new statements make a compile error. My background is in Python and Java and I'm stuck in front of C++ way of creating objects that aren't classes.
I'm translating an algorithm from C# and for machine learning and it uses an array of multidimensional arrays.
C# code:
public double Learn(int[][] observations, int symbols, int states, ...
// ...
double[][, ,] epsilon = new double[N][, ,]; // also referred as ksi or psi
double[][,] gamma = new double[N][,];
for (int i = 0; i < N; i++)
{
int T = observations[i].Length;
epsilon[i] = new double[T, States, States];
gamma[i] = new double[T, States];
}
I've decided to use the Boost library for the multidimensional array, and I have:
typedef boost::multi_array<double, 2> matrix2D;
typedef boost::multi_array<double, 3> matrix3D;
vector<matrix3D> epsilon;
vector<matrix2D> gamma;
cout << "HMM::learn >> before" << endl;
for (int i = 0; i < N; i++)
{
int T = observations[i].size();
epsilon[i] = matrix3D(boost::extents[T][states][symbols]);
gamma[i] = matrix2D(boost::extents[T][states]);
}
and I get this runtime error:
HMM::learn >> before
std::bad_alloc' what(): std::bad_alloc
The vectors have no space allocated (well it may be reserved already but you can't reference it with the array indexers). Change the lines:
epsilon[i] = matrix3D(boost::extents[T][states][symbols]);
gamma[i] = matrix2D(boost::extents[T][states]);
To:
epsilon.push_back(matrix3D(boost::extents[T][states][symbols]);
gamma.push_back(matrix2D(boost::extents[T][states]);
that should solve it. In your case since you know the array size you should reserve that much space in the vectors so that it reduces the reallocations needed:
epsilon.reserve(N);
gamma.reserve(N);

Dynamically Changing the Size of the Pointer in C++

I have the following structure
typedef struct DeviceInfo
{
char[30] name;
char[30] serial Number;
}DeviceInfo;
I am doing this
DeviceInfo* m_DeviceInfo = new DeviceInfo[4];
// Populate m_DeviceInfo
Then I wanted to re size m_DeviceInfo to 6 and want to preserve the
Previous 4 Value as well.
How to do it in c++ ?
You can't do that with regular arrays. I suggest you to use vector which is able to grow as you add more elements to it (so you don't even have to specify initial size).
The good C++ way is to use an appropriate container for that. Apparently, you should use the std::vector container, e.g:
std::vector<DeviceInfo> m_DeviceInfo;
m_DeviceInfo.resize(4);
This requires some constraints on your DeviceInfo. In particular, it should have a constructor without arguments, and copy constructors...
And your question is badly phrased. You certainly don't change sizeof(DeviceInfo*) which is probably 4 bytes on a 32 bits machine, and 8 bytes on a 64 bits one.
m_DeviceInfo points to an array of DeviceInfo of 4 elements. There is no resizing with arrays. Instead you should delete and create it with 6 elements.
DeviceInfo * m_DeviceInfo2 = new DeviceInfo[6];
memcopy( m_DeviceInfo,m_DeviceInfo2, 4 );
delete[] m_DeviceInfo;
But you should use a vector.
std::vector<DeviceInfo> m_DeviceInfo;
// or
std::vector<std::shared_ptr<DeviceInfo>> m_DeviceInfo;
To resize it
m_DeviceInfo.resize(m_DeviceInfo.size()+ 2);
You have two options in your problem and it depends if you want to use STL or not.
typedef struct DeviceInfo
{
char[30] name;
char[30] serial Number;
} DeviceInfo;
With STL:
//requires vector.h
vector<DeviceInfo> m_deviceInfo;
DeviceInfo dummy;
dummy.name = "dummyName";
dummy.serialNumber = "1234";
m_deviceInfo.insert(m_deviceInfo.begin(), dummy);
//add as many DeviceInfo instance you need the same way
or without STL:
//implement this
DeviceInfo* reallocArray(DeviceInfo* arr, int curItemNum, int newItemNumber)
{
DeviceInfo* buf = new DeviceInfo[newItemNumber];
for(int i = 0; i < curItemNum; i++)
buf[i] = arr[i];
for(int i = curItemNum; i < newItemNumber; i++)
buf[i] = null;
}
//and in your main code
DeviceInfo m_DeviceInfo = new DeviceInfo[4];
m_DeviceInfo = reallocArray( m_DeviceInfo, 4, 6 );
1) Make a new array of size that fits, and copy all elements of the old array to the new one.
2) Use the std::vector (my recommendation).
The best possible solution is using vector in your program.
Refer this site http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html#VECTOR
This site will help you to solve your problem.
Here you can push the data.No need to bother about the size of structure.
Your syntax is wrong:
DeviceInfo m_DeviceInfo = new DeviceInfo[4];
should be:
DeviceInfo* m_DeviceInfo = new DeviceInfo[4];
A better alternative would be the use of std::vector.
std::vector<DeviceInfo> vec;
//populate:
DeviceInfo inf;
vec.push_back(inf);
vec.push_back(inf);
//....
well there are several ways to do this, but
you should use the realloc function in c++. it will reallocate contiguous memory and also copies the value of previous memory into the new ones. for example:
temp_DevInfo = (DeviceInfo*) realloc (m_DeviceInfo, (2) * sizeof(struct DeviceInfo));
free(m_DeviceInfo);
m_deviceInfo = temp_DevInfo;
you do 2 * sizeof(DeviceInfo) because you want to add 2 more, plus the previous 4 is 6.
then you should free/delete the previous object.
and finally set old pointer to point to the new object you just allocated.
that should be the gist of it
look at the documentation of realloc.