I have a giant array that's being used to temporarily store pixel data (before it's written to a file). I've been having "random" crashes and someone much more proficient with C++ than myself suggested that I should put my pixel array in the heap than stack. These were all new words to me but I've read up and it makes sense but I'm struggling to set this up.
Declaring the heap array:
int *heap = new int[MAX_WIDTH * MAX_HEIGHT * 3];
This is then used by my Canvas class, which I want to hold a pointer to a specific heap:
class Canvas {
public:
Canvas(int w, int h, bool fill_transparent, int* heap);
Canvas();
int width;
int height;
int* heap;
}
Canvas::Canvas(int w, int h, bool fill_transparent, int* heap) {
if (w>MAX_WIDTH) w = MAX_WIDTH;
if (h>MAX_HEIGHT) h = MAX_HEIGHT;
width = w;
height = h;
heap = heap;
if (fill_transparent) {
for(int x=0; x<width; ++x) {
for(int y=0; y<height; ++y) {
set(x, y, transparent);
//heap->pixels[x][y] = transparent;
}
}
}
}
Creating a new canvas and passing the heap along:
Canvas new_texture(int w, int h, int* heap) {
Canvas canvas(w, h, true, heap);
// Do some things with it, using set(x,y);
return canvas;
}
And then attempting to set pixel data (Pixel is a struct with {int r, int g, int b}:
void Canvas::set(int x, int y, Pixel colour) {
if (x>=width || y>=height || x<0 || y <0) return;
// Set the heap :C
*heap[(x * (MAX_HEIGHT*3)) + y] = colour.r;
*heap[(x * (MAX_HEIGHT*3)) + y + 1] = colour.g;
*heap[(x * (MAX_HEIGHT*3)) + y + 2] = colour.b;
}
This is wrong! I just can't figure out how I should be declaring the array, storing the pointer in a class, and then accessing it. int *heap[] makes more sense to me but also doesn't work.
I'm learning on the job, and am really struggling to find an overview of how I should be doing this.
I've tried most variations that I can think of, I'm struggling to get something that works in all three places!
You would access the dynamically allocated memory using
heap[y * width * 3 + x * 3 + color]but it's both inconvenient and error prone.Your class is also lacking the special member functions to follow the rule of five which makes future bugs very likely.
I recommend using a
std::vectorwhich will manage the dynamically allocated memory for you and you also storePixels directly in thestd::vectorinstead of just multiplying the number ofints needed by 3. The struct and thetransparentconstant could look like this:intfor the individual channels inPixelmay be overdoing it a bit. Consider using a smaller type, likeuint8_tfor example.In your
Canvasclass, you could createoperator()overloads for accessing thePixels, that you then store in astd::vector<Pixel>:And the implementation of the
operator()overloads becomes a bit simpler than with your dynamically allocatedints. The constructor also tells thestd::vector<Pixel>how many pixels there should be and if they should betransparentor have the default constructedPixel:Demo