0

I have this assignment to do where I need to declare and use a dynamically allocated matrix. It's initialized as a 7X7 grid with known data (seen below)

I tried out at least a thousand different ways, but each time the compiler won't get it, it will alert me of a problem with casting int[][] to int**. I added a screenshot of the code, would love some help!

#include <cstdlib>
#include "Map.h"
typedef int size_type;
typedef int** grid_type;
grid_type ppGrid;
size_type size_h;
size_type size_w;

int mapInitializer[7][7]=
        {
        { 0 , 1 , 1 , 1 , 1 , 1 , 1},
        { 1 , 2 , 2 , 0 , 1 , 0 , 1},
        { 0 , 0 , 1 , 1 , 1 , 2 , 1},
        { 1 , 0 , 0 , 0 , 0 , 0 , 1},
        { 1 , 1 , 1 , 2 , 1 , 0 , 1},
        { 1 , 0 , 0 , 0 , 0 , 2 , 1},
        { 1 , 0 , 1 , 1 , 1 , 1 , 1}
        } ;

Map::Map(){
    grid_type ppGrid;
    realloc(ppGrid,7);
    for(int i=0;i<7;i++){
        realloc(ppGrid[i],7);
    }
    ppGrid=mapInitializer;
}
Roni Zaitsev
  • 77
  • 1
  • 2
  • 8
  • Possible duplicate of [Is 2d array a double pointer?](http://stackoverflow.com/questions/7586702/is-2d-array-a-double-pointer) – CIsForCookies May 14 '17 at 06:24
  • 3
    (1) Never hide a pointer type behind a typedef if you **care** that it's a pointer type. That's the most error prone approach possible with pointers. (2) A double pointer is not a 2d array, you can't just assign a variable of 2d array type to a double pointer. Those are incompatible types. (3) Use a `std::vector>` rather than managing memory yourself. (4) Copy the rows *one at a time*. (5) Next time post code as text, not an image. We can't copy an image into a compiler to examine the code. – StoryTeller - Unslander Monica May 14 '17 at 06:26
  • @StoryTeller Hi, thx! Updated the post with actual code rather than an image. Sadly, I have to use typedef and cannot use vectors. I wish I could. Everything should happen with dynamically allocated matrix. – Roni Zaitsev May 14 '17 at 06:41
  • @RoniZaitsev - Strictly speaking, `std::vector` does dynamic allocation as well. It's just written by C++ experts. It's also as an integral part of the language as a `for` loop. If you can't use it, don't, but item (4) still stands. I also suggest moving the memory management to a separate class that `Map` will hold (something named `GridMemory`, if you catch my drift). And finally, if your teachers insist on the typedef, they set you up for failure. You should take what they teach you with a grain of salt. – StoryTeller - Unslander Monica May 14 '17 at 06:47
  • @StoryTeller of course, I hate the use of typedef here, It only make it worse, but I can't say anything about it. The same about vectors, If I only could. Thank you about (4), I'm trying it right now. – Roni Zaitsev May 14 '17 at 07:08
  • I feel I should point out, that when I said *copy the rows* I didn't mean `ppGrid[i] = mapInitializer[i];`. That will just leak memory. Also your use of realloc is incorrect. It accept how much memory to allocate, i.e `sizeof(int) * 7` – StoryTeller - Unslander Monica May 14 '17 at 07:11

2 Answers2

1

int** means pointer on pointer. 2 dimensional matrix located in the memory directly (i.e. next row placed after current row in memroy). So if you try to dereference this pointer you will have value, but not pointer. You should copy matrix line by line or allocate one memory for whole array.

P. Dmitry
  • 1,123
  • 8
  • 26
  • I tried to allocate one memory for the whole array, but I couldn't find a way for it to accept ppGrid as it afterwards. No matter what I do, it won't accept any comparison between int** and int[][] – Roni Zaitsev May 14 '17 at 06:45
0

A pointer is not the same as an array, an array is allocated all its elements by the compiler and it's size is known at compilation time (static size) A pointer is an address and the [] operator allows you to dereference as if it were an array, but it isn't. This and the fact that an array name behaves as a pointer to it's first element makes the newbie to infer that they are the same thing.

Arrays and pointers are not the same thing Something like double matrix[7][7]; is completely different to double **matrix; and to double *matrix[7];. The first being an array of seven arrays of seven doubles, the second being a pointer to pointer to double, and the third being an array of seven pointers to double.

Pointer arithmetic allows you to move pointers as if they where iterating an array, but this also doesn't mean they are equivalent. You can move a pointer, but you cannot move an array.

Finally, if you try to get sizeof those, you'll get:

sizeof (double [7][7]) /* seven times the sizeof of an array of seven doubles == 49 times the sizeof a double */
sizeof (double *[7]) /* seven times the sizeof an array of seven pointers to double == 7 times the size of a pointer */
sizeof (double **) /* the sizeof a pointer to pointer to double == the size of a pointer */

Something that more disturbs newbies is the fact that the compiler always converts array references to pointers in C functions formal parameters, so when you see double param_matrix[][] to mean an unspecified bidimensional array, the compiler actually changes the parameter to an equivalent double **param_matrix (and it doesn't behaves also as a bidimensional array)

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31