3

I have declared a 2D array using the following way

for(int i = 0; i < rowCount; ++i){//rowCount = 5
   a[i] = new int[colCount]; //colCount = 6
}

I want to check the size of this array, I know I can just look at the numbers I put it went declaring the array, but I want to see if the code is working the way I intended.

I used "sizeof(a)/sizeof(a[0])" to get the number of rows but it is not giving the expected number

Tman
  • 70
  • 1
  • 8
  • 1
    Does this answer your question? [Finding size of dynamically allocated array](https://stackoverflow.com/questions/12617244/finding-size-of-dynamically-allocated-array) – walnut Feb 26 '20 at 07:28
  • You should avoid using `new`. Not being able to get the size of the allocation is one reason for that. Use `std::vector` instead. – walnut Feb 26 '20 at 07:28
  • 1
    That is *not* a 2D array - that's a 1D array of pointers to 1D arrays. A 2D array would be defined as `int a[N][M];`. – Sander De Dycker Feb 26 '20 at 07:30
  • Also [How do I find the length of an array?](https://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array). In particular do not use `sizeof(a)/sizeof(a[0])` to get the length of an array. As you observed here, it will give wrong results easily if you make a mistake. [This answer](https://stackoverflow.com/a/18078435/11941443) has a much better approach and since C++17 you can just use `std::size(a)`. – walnut Feb 26 '20 at 07:31
  • Sorry I misread part of your question. Please clarify how `a` is declared. Provide a [repro]. I am leaving my comments up, since they probably still apply. – walnut Feb 26 '20 at 07:33
  • @SanderDeDycker however it's necessary to know that those can only have compile-time-known sizes if wanting to achieve cross-compiler compatibility, right? – AlexGeorg Feb 26 '20 at 07:36
  • To continue with what @walnut was saying, `a` is probably [a pointer and not an array](https://www.geeksforgeeks.org/pointer-vs-array-in-c/) so sizeof(a) is likely constant to 32 or 64. If so, you sadly must store the size somewhere separately or use standard containers. – Jean Feb 26 '20 at 09:06

2 Answers2

0

The thing is that a is not really holding the 2D array. You should think of it as a is an Array of Arrays. So the size of a is just 5 while the size of each array in a is 6 (keep in mind that there is no restriction that each array in a will be with the same size). If you really want to calculate the total size you should iterate over a and sum the sizes of all the rows.

Roee Gavirel
  • 18,955
  • 12
  • 67
  • 94
  • They only want the number of rows: "*to get the number of rows*" If `a` is a pointer (likely), this will still not work. – walnut Feb 26 '20 at 07:35
0

You can use std::vector<std::vector>> as suggested and take their .size() methods, however that is not the most memory friendly. I'd suggest wrapping your array of arrays, aka pointer of pointers in a small, dedicated class which internally keeps track of the sizes, allows you to access the raw data and also has a getWidth and getHeight function. You can also easily give it convenient functions like .setAll(T value) and use templates to support any data type.

// Example program
#include <iostream>
#include <string>

template<class T>
class RawGrid 
{
    private:
        int width, height;

    public:

        RawGrid(int width, int height) : width(width), height(height)
        {
            data = new T*[width];
            for(int i = 0; i < width; i++)
                data[i] = new T[height];
        }
        ~RawGrid()
        {
            if (data)
            {
                for(int i = 0; i < width; i++)
                    delete[] data[i];
                delete[] data;                
            }
        }

        int getWidth() {
            return(width);
        }
        int getHeight() {
            return(height);
        }

    T** data = nullptr;
};


int main()
{
    RawGrid<int> grid(100, 50);

    grid.data[10][25] = 20;

    std::cout << "Data value: " << grid.data[10][25] << "!\n";
    std::cout << "Width: " << grid.getWidth() << "!\n";
    std::cout << "Height " << grid.getHeight() << "!\n";
}
AlexGeorg
  • 967
  • 1
  • 7
  • 16
  • do you mind giving me an example of how this is done? – Tman Feb 26 '20 at 07:39
  • What's your reasoning behind saying std::vector `is not the most memory friendly`? – theWiseBro Feb 26 '20 at 07:43
  • @theWiseBro each instance of vector requires some additional book keeping memory which is more than a pointer. Admittedly the difference might be small n practice. – AlexGeorg Feb 26 '20 at 07:47
  • @AlexGeorg I don't see how your implementation is more memory friendly than a vector. Afaik, apart from the raw pointer, vector just keeps `capacity`,`size` and the `allocator` part of its object. And I highly believe using an stl container is always more maintainable and, in most cases, more performance-memory efficient than custom code. But yeah, if the OP's area of interest is fixed to using 2D array in only the small cases as he says, then yes, your solution is pretty decent as well. – theWiseBro Feb 26 '20 at 07:55
  • @AlexGeorg Your example violates the rule-of-three and is not exception-safe. Your solution has the same problems as `std::vector>` would have: It allocates multiple times (each with allocator overhead in time and memory). The additional overhead from `std::vector` lies only in the size/capacity values which should not matter relative to the allocations. – walnut Feb 26 '20 at 08:00