I want to allocate a large block of memory to store image data. It will be several kilobytes in size and is basically just a large block of bytes representing each pixel for the width, height and plane for the whole image.
class MyImage
{
int* _data = nullptr;
int _width;
int _height;
int _numPlanes;
public:
~MyImage()
{
delete[] _data;
}
void defineImage(int width, int height, int numPlanes)
{
_width = width;
_height = height;
_numPlanes = numPlanes;
_data = newint[width * height * numPlanes];
}
}
to allocate my data - however, since C++ is moving away from manually managing these things I was wondering if the standard library offered a new way to deal with this situation.
just use a vector.
vector<unsigned char> data;
once you get the width and height for the current object you can grow it to fit.
why int? I said unsigned char --- most image data I have used is 3 or 4 bytes (RGB or RGBA) style. 4 bytes is a 32 bit int, so you 'can' pack a RGBA pixel into a 32 bit int, but there are 2 problems with that. First, getting say the blue pixel data out of it is more work than if it were addressed by bytes, and second 'int' can vary in size, could be 64 bits, in a few years it may be 128.
char is 1 byte on modern, major systems and can be used as a 1 byte integer (but you need to cast it to int to print it due to print utilities wanting to print the text version by default).
Your class above is small and simple and if used correctly is fine IMHO. But if you ever assign one image to another (myimage a,b; ... a= b; ) you can quickly have things go very wrong. That is the most likely trouble spot with your class, but the same idea can pop up in various ways at weird times if you just gave the class to someone else or put it in a library and it got used in unexpected ways. This is why the pointer is frowned upon -- you need a lot of stuff to handle every possible scenario that you don't need using stl containers
Thanks for your replies. The code above was meant more to illustrate my question rather than be production code. I'll look into using vector<uint8_t> for places where I need blocks of data. Most of my C++ knowledge is from 20 years ago, and I'm finding it hard to shift gears into more modern ways of doing things.
If you want to dynamically manage memory and don't want to use std::vector there are smart pointers. Singles and arrays. https://en.cppreference.com/w/cpp/memory
One caveat with using std::vector. There are two methods for accessing the elements. [] and at(). at() checks for out-of-bounds conditions so there can be considerable time/computational overhead when using it. If you are sure you won't go out of bounds when accessing the elements then use [].