-1

I thought that the following code would work. However, it is printing the first row and then throwing a segmentation fault.

const unsigned **grid = new const unsigned*[10]{new const unsigned[10]{0}};

for (int r = 0; r < 10; r++)
{
    for (int c = 0; c < 10; c++)
    {
        std::cout << grid[r][c] << " ";
    }
    std::cout << std::endl;
}

Does anyone know what I am (probably naively) doing incorrectly?

codeing_monkey
  • 43
  • 1
  • 2
  • 6
  • 1
    `new const unsigned[10]{0}` provides 1 allocation of ten `unsigned`, not the ten allocations needed to satisfy the outer dimension – user4581301 Feb 22 '22 at 20:55
  • Recommended reading: [How do I use arrays in C++?](https://stackoverflow.com/q/4810664/1553090) – paddy Feb 22 '22 at 20:55
  • You need a new statement to create an array of pointers to 1D arrays then you need to initialize it with 10 pointers to 1D rows of ints if you want to use a `int**` This is not often used outside of some very old CPUs where it can be appropriate. – doug Feb 22 '22 at 20:56
  • 1
    Expanding on above, `const unsigned **grid = new const unsigned*[10]{new const unsigned[10]{0}};` means `const unsigned **grid = new const unsigned*[10]{new const unsigned[10]{0}, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };` – user4581301 Feb 22 '22 at 21:00
  • 5
    Simplify your life: `std::vector< std::vector >` – Thomas Matthews Feb 22 '22 at 21:01
  • 1
    [or simplify your life almost as much and reap the performance benefits of a single, cache friendly allocation](https://stackoverflow.com/a/2076668/4581301). – user4581301 Feb 22 '22 at 21:04
  • Why are people so judgmental in the comments lmao. The whole purpose of this website is to ask questions... – codeing_monkey Feb 22 '22 at 21:08
  • 3
    We are engineers. We are giving objective responses, and taking the time to do so. Nobody is judging you. While you might not be getting the quick fix you think you need, you could nevertheless try to avoid taking offense, and actually consider the information that is being given to you. – paddy Feb 22 '22 at 21:12
  • Since it´s just a fixed 10x10 matrix can just use const unsigned int grid[10][10]={0} ; – convert Feb 22 '22 at 21:18
  • @convert has a good point, but note that you cannot return a simple array like this from a function. They always decay to a pointer and then go out of scope, leaving the pointer [dangling](https://en.wikipedia.org/wiki/Dangling_pointer). – user4581301 Feb 22 '22 at 21:38
  • @dangling I completly agree, but there is no return statment in this example. – convert Feb 22 '22 at 21:40

1 Answers1

1

Here are some options using dynamic allocation (of course it is simpler to use automatic allocation):

// should be delete[]'d at some point in future
auto* arr1 = new const unsigned[10][10]{};

// #include <memory>, C++14
auto arr2 = std::make_unique<const unsigned[][10]>(10);

// #include <vector>
auto const arr3 = std::vector<unsigned>(100);  // use index math

// #include <array>
using A10 = std::array<unsigned, 10>;
auto const arr4 = std::vector< A10 >(10, A10{});
M.M
  • 138,810
  • 21
  • 208
  • 365
  • You have also neglected the CRUCIAL call to delete[] (your arr1 array). This is C++ 101, It MUST be learned by all C++ programmers. This is called a memory leak and can lead to a program running out of memory if the leak is in a loop. – Alex Feb 22 '22 at 22:42
  • 3
    @Alex the question was how to declare it, not how to delete it. Maybe the code is intended to be inside a function that returns the pointer to the array, in which case deleting it immediately would be incorrect. – M.M Feb 22 '22 at 22:44