I'm having problems declaring a multidimensional dynamical array in c style. I want to declare dynamically an array like permutazioni[variable][2][10], the code i'm using is as following (carte is a class i defined):
#include "carte.h"
//other code that works
int valide;
carte *** permutazioni=new carte**[valide];
for (int i=0; i<valide; i++){
permutazioni[i]=new carte*[2];
for (int j=0; j<2; j++) permutazioni[i][j]=new carte[10];
}
the problem is, whenever i take valide=2 or less than 2, the code just stops inside the last for (int i=0; i<valide; i++) iteration, but if i take valide=3 it runs clear without any problem. There's no problem as well if i declare the array permutazioni[variable][10][2] with the same code and any value of valide. I really have no clue on what the problem could be and why it works differently when using the two different 3d array i mentioned before
You show a 3D array declared as permutazioni[variable][10][2] but when you tried to dynamical allocate that you switched the last two dimensions.
You can do something like this:
#include <iostream>
#define NVAL 3
#define DIM_2 10 // use some more meaningfull name
#define DIM_3 2
// assuming something like
struct Card {
int suit;
int val;
};
int main() {
// You are comparing a 3D array declared like this:
Card permutations[NVAL][DIM_2][DIM_3];
// with a dynamical allocated one
int valid = NVAL;
Card ***perm = new Card**[valid];
// congrats, you are a 3 star programmer and you are about to become a 4...
for ( int i = 0; i < valid; i++ ){
perm[i] = new Card*[DIM_2];
// you inverted this ^^^ dimension with the inner one
for (int j = 0; j < DIM_2; j++)
// same value ^^^^^
perm[i][j] = new Card[DIM_3];
// inner dimension ^^^^^
}
// don't forget to initialize the data and to delete them
return 0;
}
A live example here.
Apart from that it is always a good idea to check the boundaries of the inddecs used to access to the elements of the array.
How about using this syntax? Haven't tested fully with 3 dimensional arrays, but I usually use this style for 2 dimensional arrays.
int variable = 30;
int (*three_dimension_array)[2][10] = new int[variable][2][10];
for(int c = 0; c < variable; c++) {
for(int x = 0; x < 2; x++) {
for(int i = 0; i < 10; i++) {
three_dimension_array[c][x][i] = i * x * c;
}
}
}
delete [] three_dimension_array;
Obviously this could be c++ 11/14 improved. Could be worth a shot.
Related
I'm working on knight's tour problem, and want to define a class, but I am having trouble with initialize an array defined by user. So the user inputs from the command line argvs are the chessboard lengths mX and nY; and a starting position(x,y). So basically, how do I initialize an array that's defined by the user?
First question: In the public part, is it right to declare int ** tour?
Second question: How do I refer to the array tour in the following functions in the same class?
Third question: In main, I called K.knight to initialize an array of dimension specified by the user, but it wasn't initialized. How do I initialize an array in main using the function K.knigt(), and be able to use the array in the following function K.knightfunc()?
class Ktour{
public:
int xSize; //m
int ySize; //n
int ** tour; //array to be initialized
int solutionsCount; //tracking solutions
int position; //position count, from 0 to m * n -1
// initialize tour matrix
void knight(int M, int N) {
position = 1;
solutionsCount = 0;
xSize = M;
ySize = N;
tour = new int * [xSize];
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
tour[i][j] = 0;
std::cout << tour[i][j] << std::endl;
}
}
}
....some other functions defined in between...
....
....
};
...
// main
int main(int argc, char *argv[])
{
Ktour K;
//user inputs chessboard length mX and nY; and a starting position(x,y)
int mX = atoi(argv[1]);
int nY = atoi(argv[2]);
int x = atoi(argv[3]);
int y = atoi(argv[4]);
//initialization
K.knight(mX, nY);
//run the recursive function;
K.knightFunc(x,y);
return 0;
}
Yeah, it seems more logical to initialize in the ctor. My take on this is you are creating an array of int pointers, and have not yet allocated the ints that are being pointed to.
You have a few possibilities:
If we are to think of a common chessboard, then since the array size is known in advance, and it's not especially big, just create it in the class:
class Ktour{
...
int tour[8][8];
...
}
although some purists might say you should only "new" such arrays. If it is a much larger array, you certainly should.
A more straightforward syntax like what you're trying to do, for handling arrays of unknown size would be:
class Ktour{
...
int **tour=0;
KTour(int M, int N) {
tour = new int * [M];
for (int i=0; i<M; ++i)
tour[i] = new int [N];
};
~KTour() {
for (int i=0; i<M; ++i)
delete [] tour[i];
delete [] tour;
};
...
}
You access it quite simply, with:
std::cout << tour[i][j];
The above kind of coding is error-prone. To reduce your future strife with memory access errors, you really should use STL container classes (or Boost ones, or Qt ones when using Qt, if their size isn't too limited - but you can use STL in Qt also), since they produce an error in debug when you access out-of-bounds subscripts for your arrays, instead of, e.g. overwriting important pointers, etc. Thus, you could use something like:
class Ktour{
...
std::vector < std::vector<int> > Tour;
KTour(int M, int N) {
// tour.resize(M); // not needed.
tour.assign(M, std::vector <int> (N, 0));
};
~KTour() {
// No need to delete
};
...
}
and you access it with
std::cout << tour[i][j];
(Note: The extra lines in the code are some artifact of the <pre> and <code> tags; necessitated by not all of my indented lines being recognized as code.)
I am completely stuck on this problem... The code structure that is given is as follows:
typedef struct _myvar{
uint32_t someInt;
uint32_t *ptr;
} myvar;
...
myvar **var;
..
var = new myvar*[x]; // where x is an int
for(int i = 0; i < y; i++){ // y is usually 2 or 4
var[i] = new myvar[z]; //create dynamic 2d array
for(int j = 0; j < z; j++){
var[i][j].ptr = new int[b]; //where b is another int
}
}
What happens is I want to create a 2d structure that has one part of it being 3d i.e. the ptr is just a pointer to an array of ints.
My code compiles but I get seg faults in trying to allocate memory so ptr can point to it. I tried working on this for about an hour and figure it was time for some help.
Thanks!
EDIT1: Fixed code issue in regards to comment on code not compiling.. Secondly... I cannot use vectors as much as I would like to... The data structure that I have there is what I have to use.
EDIT2: b is dynamic and set at the command line. For testing purposes use 16.
I think you are getting confused with your indices. In your first loop you use var[i], so i must stop at x, not at y. For the columns I have used j and y. Not sure what z is.
Then, as pointed out by others, you shouldn't mix int and uint32_t.
Try this:
#include <iostream>
using namespace std;
typedef struct _myvar{
uint32_t someInt;
uint32_t *ptr;
} myvar;
int main() {
myvar **var;
int x = 3;
int y = 4;
var = new myvar*[x]; // where x is an int
for(int i = 0; i < x; i++) { // i stops at x
var[i] = new myvar[y]; //create dynamic 2d array
for(int j = 0; j < y; j++){
var[i][j].ptr = new uint32_t[16]; // used 16 for testing
}
}
return 0;
}
In my code, I defined a 3D array to store the date on CUDA kernel.The code just like this:
if(k<2642){
double iCycle[100], jCycle[100];
int iCycleNum = 0, jCycleNum = 0;
for(double i=0; i<=1; i+=a, ++iCycleNum){
iCycle[iCycleNum] = i;
for(double j=0; j+i<=1; j+=c, ++jCycleNum){
jCycle[jCycleNum] = j;
[...]
r=(int)color[indexOutput];
g=(int)color[indexOutput+1];
b=(int)color[indexOutput+2];
d_RGB[k][iCycleNum][jCycleNum].x=r;//int3 (*d_RGB)[100][100]
d_RGB[k][iCycleNum][jCycleNum].y=g;
d_RGB[k][iCycleNum][jCycleNum].z=b;
}
}
}
In every cycle, there is an r,g,b. I want to store the r,g,b in d_RGB[k][iCycleNum][jCycleNum],then I need to pass them to the host. But in this case, every k has a different iCycleNum and jCycleNum, and I do not know the value of them, so the 3D array here is so awaste of space and may be it could bring some bugs. I wonder if it is a way to change the 3D array into a 1D one like this: d_RGB[k+iCycleNum*x+jCycleNum*x*y].
Sorry, my English is not so good to decribe it clearly, so if you can not get what I mean, please add a comment. Thank you.
Actually a "classic" 3D array is organized in the memory as a 1D array (since the memory is 1D oriented).
The Code:
int aiTest[5][5][5] = {0};
int* piTest = (int*)aiTest;
for (int i = 0; i < 125; i++)
{
piTest[i] = i;
}
does not make any memory violations - and the element aiTest[4][4][4] will have the value of 124.
So the answer: just cast it to the right type you need.
int arr[5][6][7];
int resultant_arr[210];
int count=0;
for(int i=0;i<5;i++)
{
for(int j=0;j<6;j++)
{
for(int k=0;k<7;k++)
{
if(count<210)
{
resultant_arr[count]=arr[i][j][k];
count++;
}
}
}
}
I have been working on this program for quite some time. This is just two of the functions extracted that are causing a memory leak that I cant seem to debug. Any help would be fantastic!
vector<int**> garbage;
CODE for deleting the used memory
void clearMemory()
{
for(int i = 0; i < garbage.size(); i++)
{
int ** dynamicArray = garbage[i];
for( int j = 0 ; j < 100 ; j++ )
{
delete [] dynamicArray[j];
}
delete [] dynamicArray;
}
garbage.clear();
}
CODE for declaring dynamic array
void main()
{
int ** dynamicArray1 = 0;
int ** dynamicArray2 = 0;
dynamicArray1 = new int *[100] ;
dynamicArray2 = new int *[100] ;
for( int i = 0 ; i < 100 ; i++ )
{
dynamicArray1[i] = new int[100];
dynamicArray2[i] = new int[100];
}
for( int i = 0; i < 100; i++)
{
for(int j = 0; j < 100; j++)
{
dynamicArray1[i][j] = random();
}
}
//BEGIN MULTIPLICATION WITH SELF AND ASSIGN TO SECOND ARRAY
dynamicArray2 = multi(dynamicArray1); //matrix multiplication
//END MULTIPLICATION AND ASSIGNMENT
garbage.push_back(dynamicArray1);
garbage.push_back(dynamicArray2);
clearMemory();
}
I stared at the code for some time and I can't seem to find any leak. It looks to me there's exactly one delete for every new, as it should be.
Nonetheless, I really wanted to say that declaring an std::vector<int**> pretty much defies the point of using std::vector itself.
In C++, there are very few cases when you HAVE to use pointers, and this is not one of them.
I admit it would be a pain to declare and use an std::vector<std::vector<std::vector<int>>> but that would make sure there are no leaks in your code.
So I'd suggest you rethink your implementations in term of objects that automatically manage memory allocation.
Point 1: If you have a memory leak, use valgrind to locate it. Just like blue, I can't seem to find a memory leak in your code, but valgrind will tell you for sure what's up with your memory.
Point 2: You are effectively creating a 2x100x100 3D array. C++ is not the right language for this kind of thing. Of course, you could use an std::vector<std::vector<std::vector<int>>> with the obvious drawbacks. Or you can drop back to C:
int depth = 2, width = 100, height = 100;
//Allocation:
int (*threeDArray)[height][width] = malloc(depth*sizeof(*threeDArray));
//Use of the last element in the 3D array:
threeDArray[depth-1][height-1][width-1] = 42;
//Deallocation:
free(threeDArray);
Note that this is valid C, but not valid C++: The later language does not allow runtime sizes to array types, while the former supports that since C99. In this regard, C is more powerful than C++.
I want to create and initialize a 2D array but the initialization is failed. I encounter "The program has unexpectedly finished." in Qt Creator.
What is wrong?
in .h file
private:
int pop;
int d;
float **uye;
in .cpp file
pop=50;
d=12;
uye = new float*[pop];
for(int i=0; i<d; i++) uye[i] = new float[d];
for(int n=0; n<pop; n++)
{
for(int m=0; m<d; m++)
{
uye[n][m] = (float) n*m;
}
}
The first loop for(int i=0; i<d; i++) should probably be for(int i=0; i<pop; i++). Otherwise, you are only reserving space for 12 elements, but later try to access 50.
Note that having raw pointer members is considered a very bad idea in modern C++, because you need to worry about copying semantics. Better use a flat std::vector<float> and do the 2D to 1D mapping manually, or use a std::vector<std::vector<float> > with convenient access syntax.
I would prefer the second version. Without seeing more context:
pop = 50;
d = 12;
uye = std::vector<std::vector<float> >(pop, std::vector<float>(d));
The nested for loops that follow work exactly the same, no changes required.
What is wrong?
You're not using std::vector (that's one of the things that's wrong, #FredO covered the other thing).
#include <vector>
int main(){
typedef std::vector<float> inner_vec;
typedef std::vector<inner_vec> outer_vec;
int pop = 50, d = 12;
// first parameter to vector is its size
// second is what every element should be initialized to
outer_vec uye(pop, inner_vec(d));
for(unsigned n = 0; n < uye.size(); ++n){
for(unsigned m = 0; m < uye[n].size(); ++m){
uye[n][m] = (float)n*m;
}
}
}