-2

In C++ when I perform the following action,

int* b = new int[5];

new int[5]; returns an int* which I use b to point to.

However, when performing,

int** c = new int[5][10];

I receive an error, cannot convert ‘int (*)[10]’ to ‘int**’ in initialization.

Why does this syntax not work, however it will in other situations such as,

int** matrix = new int* [5];
for(int i=0; i < d1; i++){
    matrix[i] = new int[10];
}

In the above example, matrix is a pointer to an array which contains 5 elements of type int *, therefore is int** c = new int[5][10]; not accomplishing the same thing? I am creating c, a pointer to an array of 5 elements of type int *, therefore the type should be int**?

My question I guess is simply, why would int** c = new int[5][10]; throw me a cannot convert ‘int (*)[10]’ to ‘int**’ in initialization but it works in the other example provided?

memelord23
  • 84
  • 1
  • 2
  • 11
  • 6
    Arrays aren't pointers and vice versa. – πάντα ῥεῖ Apr 05 '23 at 07:50
  • 2
    `new int[5][10]` creates an array of 5 arrays of size 10. 5 rows of 10 columns. It's a pointer to an array of size 10. – 273K Apr 05 '23 at 07:50
  • 1
    `new int[5][10]` creates a pointer to an array, not a pointer to a pointer. – Some programmer dude Apr 05 '23 at 07:55
  • 3
    Also, please don't use pointers and `new` for plain arrays. If the size is known at compile-time and are not expected to change, consider `std::array`. Otherwise use `std::vector`. – Some programmer dude Apr 05 '23 at 07:55
  • 5
    You will get burned by believing that an `int **` is the same as a `int[5][10]`. Either you work with `int[5][10]` throughout your code, or you work with `int **` throughout your code -- you cannot mix and match them, pretend one is the other, etc. If you dynamically built your "2D-array" using `int**` as the base, then you have to use `int **` as parameters, return values, etc. – PaulMcKenzie Apr 05 '23 at 08:14
  • 2
    Just use `std::array` or `std::vector` already and forget about C-style arrays and ditch all that manual memory management. You'll have fewer bugs, simpler code and sleep better at night. – Jesper Juhl Apr 05 '23 at 08:44
  • This might answer your question: https://stackoverflow.com/questions/24104482/difference-between-pointer-to-an-array-and-pointer-to-the-first-element-of-an-ar – SomeoneWithPassion Apr 05 '23 at 11:40
  • @SomeoneWithPassion Thanks. I've been reading the replies but I am not sure any actually answered it to the degree I actually understood. – memelord23 Apr 05 '23 at 12:05

1 Answers1

0

I'm not sure why you think int** c = new int[5][10]; and int** matrix = new int* [5]; are the same syntax, because they're definitely not.

First, this is how you can accomplish this:

typedef int row10_t[10];

row10_t* matrix = new int[5][10];

Now you can use it

matrix[0][1] = 5;
matrix[3][5] = 4;

The issue though, is you've tagged this as a C++ question, but this is all entirely C programming. You really should do it the C++ way if you plan on doing this with C++ as others have warned; there are many advantages. You could do it like this:

std::vector<std::vector<int>> matrix(5,std::vector<int>(10,3));

matrix[1][0] = 5;

You'll need to initialize the vectors with however you need. Maybe not this way, maybe exactly like this, but that is up to you. In a vector, the values must be set before you can access them because the vector needs to allocate the proper space for the data.

You can even use a pointer on this since vectors use contiguous memory allocation, but again, this is C++. The proper way to iterate a vector is to use the iterator, not a pointer. Here is an example using a range based loop for better readability:

for(auto& row : matrix)
{
    for(auto& col : row)
    {
        std::cout << col << " ";
    }

    std::cout << std::endl;
}

Which will output the matrix with our change in it:

3 3 3 3 3 3 3 3 3 3 
5 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 
3 3 3 3 3 3 3 3 3 3 

The 3s are what we set as initial values for every entry, but you can set this to whatever you want.

deviantgeek
  • 121
  • 3