2

I have a C++ class with a member that is supposed to be a two dimensional array. I want to declare my array as a member in the header file of the class. Then in the constructor of my class I want to initialize my array with a size (given to the constructor) and fill it with zeros.

I have a working example of what I want in java:

class Obj {
    int[][] array;
    public Obj(int sizex, int sizey) {
        array = new int[sizex][sizey];
    }
}

public class Main
{
    public static void main(String[] args) {
        Obj o = new Obj(12,20);
    }
}

I do not want to mess with pointers or alloc() and free(). As my class is supposed to be basically a wrapper for this array, I want to keep it simple.

I have thought about using std::vector, but as the array is never being resized after its initialization, I feel like vector is a little overpowered... Is there a better way than this: ?

#include<vector>

class Obj {
    std::vector<std::vector<int>> array;
    public:
    Obj(int xsize, int ysize) {
        std::vector<std::vector<int>> newArray(xsize, std::vector<int>(ysize, 0));
        array = newArray;
    }
};

int main()
{
    Obj o(12,20);
}
JaMiT
  • 14,422
  • 4
  • 15
  • 31
Torge Rosendahl
  • 482
  • 6
  • 17
  • 1
    Why would a `std::vector` be "overpowered" for this? You could create dynamically allocated arrays manually, but then you need to also correctly keep track of their size. Either way it would be roughly the same result – UnholySheep Sep 15 '21 at 10:10
  • `std::unique_ptr` see here: https://stackoverflow.com/questions/16711697/is-there-any-use-for-unique-ptr-with-array/16711846. Though, I am not sure how well that works for 2d – 463035818_is_not_an_ai Sep 15 '21 at 10:13
  • @UnholySheep Because I am only going to access it via `array[index]` and never use push, pop, the iterators or any other fancy stuff. – Torge Rosendahl Sep 15 '21 at 10:14
  • @463035818_is_not_a_number The linked post literally says "Don't use it." xD – Torge Rosendahl Sep 15 '21 at 10:15
  • @TorgeRosendahl I dont see where you found that. The accepted answer states: "you use unique_ptr when you need to". Requireing to forbid resizing is what makes you need something different from a vector – 463035818_is_not_an_ai Sep 15 '21 at 10:17
  • https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new See if this helps – Ahmad Anis Sep 15 '21 at 10:17
  • Are the dimensions known at compiletime? – Ted Lyngmo Sep 15 '21 at 10:29
  • @TedLyngmo No. There are going to be multiple Objects with different sized arrays. – Torge Rosendahl Sep 15 '21 at 10:31
  • @TorgeRosendahl Ok, but still, are the sizes of those objects known at compiletime? – Ted Lyngmo Sep 15 '21 at 10:34
  • 1
    @TedLyngmo No they are not. – Torge Rosendahl Sep 15 '21 at 10:39
  • Note that for a 2-dimensional grid like this using a 1-dimensional array is usually a better solution, see how to do so in e.g.: https://softwareengineering.stackexchange.com/questions/212808/treating-a-1d-data-structure-as-2d-grid – UnholySheep Sep 15 '21 at 11:49

2 Answers2

4

std::vector is the best match here. (As you said, in most cases raw arrays and pointers could be avoided. Also see How can I efficiently select a Standard Library container in C++11?)

And you can initialize the data member directly in member initializer list instead of assigning in the constructor body after default-initialization, e.g.

Obj(int xsize, int ysize) : array(xsize, std::vector<int>(ysize, 0)) {
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

Other than using std::vector you can just allocate memory of the required size from the heap.

class Obj {
    int** arr;
    int x, y;
public:
    Obj(int sizex, int sizey) : x(sizex), y(sizey) {
        arr = new int*[sizex];
        for (unsigned i = 0; i < sizex; i++) {
            arr[i] = new int[sizey];
        }
    }

    //IMPORTANT TO DELETE, OTHERWISE YOU'LL GET A MEMORY LEAK
    ~Obj() {
        for (unsigned i = 0; i < x; i++) {
            delete[] arr[i];
        }
        delete[] arr;
    }
}
  • 2
    Though you might wanna use smart pointers (simple google search will do) instead of raw pointers so you don't have to bother with deallocating the memory. – Jasper Niebuhr Sep 15 '21 at 10:46
  • 1
    And with smart pointer, rule of 5/3/0 is respected, contrary to your example, copy/move constructor/assignment are missing. – Jarod42 Sep 15 '21 at 13:05