Essence of the question. There is a class:

class a { private: int **something; public: a(); ~a(); }; 

Actually, how to allocate memory for a two-dimensional dynamic array? Or rather, where? Some sources indicate that it is necessary not to “overload” the constructor with unnecessary calculations and memory allocation, but to put everything in a different method.

 a(){something = nullptr;} void doMemory(){ /* выделение памяти */ } ~a(){if(something != nullptr) /* высвобождаем */);} 

In my opinion, “shove everything into another method” is interesting if we create more objects and they just lie in memory and wait in the wings, and when this hour comes, we take an object to allocate memory for it and immediately work with it, and then lies waiting in the wings.

    3 answers 3

    When to select?

    You need to allocate memory in the constructor, free it in the destructor. This is an implementation of one of the most important concepts of C ++ - RAII (resource acquisition is initialization). If it is broken, the program will either be unreliable, or it will be necessary to follow in each method whether memory is allocated.

    Select a large block or matrix of pointers?

    It depends on the size and on what needs to be done with this matrix in the future.

    If a program works with gigabytes of data, and works more than once, but in several passes (allocating and freeing memory between them), it may turn out that the address space is highly fragmented, and there is simply no such long piece as you need.

    For 64 bits, this is not so relevant, but there are 32 bit systems in the world (in cell phones and so on).

    If this data has to be processed in parallel on a multi-core system with NUMA , and you have allocated a large block of memory, this same NUMA will put sticks in your wheels when the processors do not get into their memory banks for data - if you allocate line by line the probability of this will be less.

    Total: Each data processing scenario requires an individual choice of the way they are stored.

      I'll start from the end. If there are a lot of constructors, then it is quite possible to put the general functionality into a common method, and call it in the constructor (or use the new ability to call one constructor from another). It is logical and your consideration - to postpone the allocation of memory until the moment it is required. Although from the point of view of convenience it will be a little worse - you will have to monitor the state all the time, and delete it, perhaps, not in the destructor, but as soon as it is no longer needed.

      But as for the allocation of memory for int** , it always gives me a question - is it necessary? Why do you need a two-dimensional array? In the end, it is the same one-dimensional, but with the conversion of indices. Do you absolutely need to refer to it as with [row][col] ? In the end, no one bothers to define the operator [] , which will return a pointer to the desired string, or operator()(size_t,size_t) and access the array element as a(row,col) . But this is my personal opinion, and then let the professionals speak out. But when I see

       something = new int*[rows]; for(int i = 0; i < rows; ++i) something[i] = new int[cols]; 

      "it begins to itch in the most immodest places" (c) :)

      Once again - this is purely my opinion. But it seems to me that

       something = new int[rows*cols]; 

      less, so to speak, error-prone ...

      • But if you select an array of arrays, then it can be fragmented, and there can be problems with a continuous piece, especially if you plan to change the size (continuous can not be expanded at all), but it all depends on the task. And since tag with ++ then I would write vector vectors better ... - pavel

      My opinion, define your own type for a two-dimensional array, which will operate on low-level objects inside. Then you can use it everywhere without worrying about allocating and cleaning up memory. RAII - getting a resource is initializing.

       template<typename T> class DualArray { public: DualArray(int sizeX, int sizeY) : _sizeX(sizeX), _sizeY(sizeY) { _buffer = new T[sizeX * sizeY]; } ~DualArray() { delete _buffer; } void set(int x, int y, const T &t) { _buffer[y * _sizeX + x] = t; } T get(int x, int y) const { return _buffer[y * _sizeX + x]; } private: int _sizeX, _sizeY; T *_buffer; };