2

How do I create a pointer to a 2D array of pointers? I'm trying to mutate a 2D array with different methods outside of main as well as work with it inside of main. I've had luck creating a pointer to a 2D array but I can't seem to initiate all indexes of the array to null. I can't seem to assign values either unless I pass the array to a method. This is what I tried:

BoardObject ** board;
board = malloc(BOARD_SIZE * sizeof(BoardObject));

for (int i = 0; i < BOARD_SIZE; i++){
    board[i] = malloc(BOARD_SIZE * sizeof(BoardObject));
}
for (int i = 0; i < BOARD_SIZE; i++){
    for (int j = 0; j < BOARD_SIZE; j++){
        board[i][j] = NULL;
    }
}

I get an error that says I can't assign type *void to BoardObject. I am probably doing it wrong but couldn't seem to find any similar issues on stack exchange. If possible please explain the solution to me. Thank you!

Note: BoardObject is a struct.

14
  • 2
    Is there a reason why you need such an obscure data type as a pointer-to-pointer lookup table? Why can't you use a real 2D array and allocate it properly, instead of allocating segments all over the heap? Commented Apr 25, 2014 at 11:31
  • 1
    board = malloc(BOARD_SIZE * sizeof(BoardObject*)); Commented Apr 25, 2014 at 11:32
  • @Lundin: I was actually uncertain as to how to approach this at all, this was what I came up with. I just want a 'simple' pointer to a 2d array that I can use like a regular array. Thanks for the link. Commented Apr 25, 2014 at 11:44
  • 1
    @Mocking Indeed. Which is why I started by asking if you actually needed a pointer-to-pointer array (a.k.a. a lookup table). If that's what you need, then you actually need to add a few more stars: double* (*A)[n] = malloc(sizeof(double*[n][n]));. But start by defining what you need, before attempting to find a solution for it. In other words, what's the actual problem you are trying to solve. Commented Apr 25, 2014 at 12:02
  • 1
    Assuming that these objects are of a generic nature, it rather sounds like you need a 2D array of structs, where each struct contains one enum (type of object at this position) and one void pointer to the actual object (if needed). At any rate, you definitely want a true 2D array allocated in adjacent memory. Commented Apr 25, 2014 at 12:48

4 Answers 4

2

I can't seem to initiate all indexes of the array to null

Use calloc().

board = malloc(BOARD_SIZE * sizeof(BoardObject));

This code says "take a pointer-to-pointer and have it point to an array of BOARD_SIZE objects". That doesn't make any sense if you want to make an array of pointers. You should have allocated sizeof(BoardObject*).

Sign up to request clarification or add additional context in comments.

Comments

1

Make the following change

board = malloc(BOARD_SIZE * sizeof(BoardObject*));

Each board[i] is a pointer to BoardObject.

Why it is giving error?

Because, board[i][j] is of BoardObject type, not BoardObject *. NULL is defined as (void *)0. Hence, you cannot assign and pointer to BoardObject. Rather, use memset or calloc as explained by others.

3 Comments

A void* can be implicitly converted to any other pointer type. Do not cast the result of malloc for this reason.
@Lundin: You are right. In C, it is implicitly converted to any other pointer type. But not in C++.
So? The question is about C.
0

Just addressing what seems to be the main issue:

board[i][j] = NULL;

board[i][j] denotes a BoardObject. This code has the same problem as:

BoardObject b = NULL;

Hopefully it's clear why this doesn't work: a BoardObject is a struct, so the only thing you can initialize it with is a brace-enclosed initializer list, e.g.

BoardObject b = { 1, "foo", 5.5 };

Or if you have designed your object to work with all fields zero-initialized,

BoardObject b = { 0 };

Now, you can't specify a brace-enclosed initializer list to memory allocated via malloc. But you can copy structs by value:

BoardObject const b = { 0 };
// ...
board[i][j] = b;

This is more portable than using calloc, which sets all bits to zero. It's system-dependent whether floating-point types or pointer types have all-bits-zero as a valid representation of their zero value, although that is true for common modern systems so you would usually get away with it.

Comments

-1

malloc returns a void pointer which you must then cast to the required type. In this case...

board = (BoardObject**) malloc( ( BOARD_SIZE * BOARD_SIZE ) * sizeof(BoardObject ) );

The reason for this is that C has no concept of any base Object type, and therefore void is required for the return from malloc such that it may allocate memory of any type.

You also, as shown in your loops need to allocate more space to your board as demonstrated in my sample code above...

I hope this helps...

3 Comments

A void* can be implicitly converted to any other pointer type. Do not cast the result of malloc for this reason.
This is hopeless, board must point to pointers and you didn't malloc any pointers.
Yep, really the outer array should be allocated, and then the inner arrays allocated, and addresses linked between :). That's the way I'd do it if I were to write some C anyways. Though, in C, sometimes it's best to avoid 2D arrays, syntax can be complex to say the least...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.