I'm working on a school project written in c++. I am trying to generate an array of rgb colours based on user input, for a program that generates fractals(irrelevant).
I found the need to use a pointer to a 2D array. The pointer has a global scope because it needs to be accessed across multiple files, in multiple functions.
There is no problem with the declaration of the pointer. It is as such:
in "global.h"
int **ptr;
int palette[10][3];
//all the statements like #ifndef GLOBAL_H_INCLUDED, etc are present
in main.cpp
extern int **ptr;
extern int palette[10][3];
void gen_array();
int main()
{
//initialize values of palette
//palette is basically list of colors that the user selects for the
//desired blend of colors to appear on the screen
gen_array();
}
in void gen_array(), in main.cpp
void gen_array()
{
int i=0, size=0, size_arr=0;
//size is a variable helpful in calculating "size_arr", which is the size of the dynamic array to be initialized
while(palette[i][0]!=256)
{ //calculates "size" }
for(int i=0; i<size-1; i++)
{
//to find "size_arr"
}
ptr= new int*[size_arr]();
for(int i = 0; i < size_arr; ++i)
{
ptr[i] = new int[3];
}
//the following piece of code enter's values column-wise into the array
int s=0;
for(int i=0; i<size-1; i++)
{
for(int k=0; k<3; k++)
{
int x=-1, a=0, b=0;
a= palette[i][k] - palette[i+1][k];
b= palette[i][k];
if(a<0)
{
a= -a;
x=1;
}
for(int j=0; j<=a; j++, s++)
{
ptr[i][k] = b;
//cout<<*(*(ptr+i)+k)<<' ';
b= b+ x;
}
b= b-x;
for(int j=a+1; j<=diff[i]; j++, s++)
{
ptr[i][k] = b;
cout<<ptr[i][k]<<' ';
}
cout<<endl;
}
}
//this output's the array that the pointer points to, on the screen
for(int i=0; i<size_arr; i++)
{
for(int j=0; j<3; j++)
{
cout<<ptr[i][j]<<' ';
}
cout<<endl;
}
}
The problem is that, the data is getting generated and inputted in the array correctly [in the second-last for loop], but when outputting it [the last for loop] I'm getting junk values.
The data inputted [the correct values] as obtained from the cout statements [that are now commented] is this [printed column-wise] whereas the O/P given out is this [printed row-wise].
If it is required to be know, "size" (in this case) =2, size_arr=256 and palette[0]={0, 0, 255} and palette[1]={0,255,0}.
Can anybody point out what the problem is, and whether it has something to do with the pointer initialization?
Even without reading all the program code like
for(int j=0; j<=a; j++, s++)
{
ptr[i][k] = b;
//cout<<*(*(ptr+i)+k)<<' ';
b= b+ x;
}
looks clearly wrong. At each iteration you are writing to ptr[i][k] and the loop doesn't change ptr, i or k. This means that it will keep writing to the very same location during the loop.
Look at your int i in the loop you're using to fill int** ptr. If size = 2 then you're never going to advance ptr far enough to fill the array. Consider filling the array like this:
for(int i = 0; i < size_arr; ++i){//for every pixel in the main array
for(int k = 0; k < 3; ++k){//for every subpixel
int my_value = ...;//calculate the value for this entry
*(*(ptr+i)+k) = my_value;//assign
Better yet, use a struct named pixel containing Uint8 r,g,b and allocate as pixel* ptr = new pixel[size] and iterate over pixels and assign ptr[i].r ptr[i].g ptr[i].b
Related
I am trying to create a huge 2D array in c++ like this :
float array[1000000][3];
I have to store some values in this array which has 3 components. This will be done iteratively by two for loops of 1000 loops.
When I try to run this I get an error :
Segmentation fault
Here is a bit of my code :
int m=0,c=0;
float error;int count=0;
array<array<float, 1000000>, 3> errors;
for(int i=0; i<1000; i++){
for(int j=0; j<1000; j++){
error=distance(j+20,m,c,1000-matrix(1,j));
errors[count][0]=error;
errors[count][1]=m;
errors[count][2]=c;
c++;
count++;
}
m++;
c=0;
}
sort(errors.begin(), errors.end());
cout<<errors[0][0]<<endl<<errors[0][1]<<endl<<errors[0][2]<<endl;
The error continues even after commenting out the sort...
matrix(1,j) is a matrix and I am accessing its elements using this method.
I want minimum value of error and the set of values of m and c for which error is minimum.
Is there any way I can achieve this?
Thanks in advance.
You can use array to easily perform your task. Here what you can:
#include<array>
using namespace std;
Then, let create your data array:
const int N = 1000000;
const int M = 3;
array<array<float, N>, M> my_array;
You can fill this newly created array by doing:
for(int i=0; i < N; i++){
for(int j=0; j < M; j++){
my_array[i][j] = 0.0f; // Just for example
}
}
For more information on how to use array library, please see here
If you don't want to use array, you can also proceed as follows:
const int N = 10000000;
const int M = 3;
float *my_array
my_array = new float[N*M]; // give it a memory on the stack
if(my_array == nullptr){
cerr << "ERROR: Out of memory" << endl;
}
for(int i=0; i < N; i++){
for(int j=0; j < M; j++){
*(my_array + i*N + j) = 0.0f; // Just for example
}
}
Make sure you release the memory you acquired by doing:
delete [] my_array;
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.
I have this vector of int from which I have to save the values to a 2D array.I though it was straight forward, but it seems that for i+j, when j becomes 0, the next integer to be saved is saved over the last one.They overlap. Can you please tell me how to fix it ? Here is the code:
vector<int> temp_table;//filled it in previous code, just for info
int** arr_table =new int* [number_of_states];
for(int i = 0; i < number_of_states; i++)
{
arr_table[i] = new int[alphabet.size()];
}
for(int i=0;i<number_of_states;i++)
{
for(int j=0;j<alphabet.size();j++)
{
arr_table[i][j]=temp_table.at(i+j);//This is where the overlapping occurs
//when j=0.How to fix it to save the correct data?
}
}
for(int i=0;i<number_of_states;i++)
{
for(int j=0;j<alphabet.size();j++)
{
cout<<arr_table[i][j]<<" ";
}
cout<<endl;
}
You want scale your i indexing by alphabet.size() to take into account the rows that have already been added:
for(int i=0;i<number_of_states;i++)
for(int j=0;j<alphabet.size();j++)
arr_table[i][j]=temp_table.at(i * alphabet.size() + j);
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 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;
}
}
}