0

I am making a simple game, which needs me to create a board of size defined by the user.

I have been writing a function that is supposed to return the board (matrix) that I will be using for my game, but I can't seem to get it to work.

I tried using the nested for loop method to print out the matrix in the main function, but I have troubles implementing it and returning it from a function.

int* boardStateDead(int width, int height){

    int* board_dead_state[width][height];

    for(int i = 0; i < height; i++){

        for(int j = 0; j < width; j++){
            board_dead_state[i][j] = 0;

        }
    }
    return  board_dead_state;
}

I expect the function to be able to return a pointer to the matrix that I just made.

kelbimon
  • 3
  • 1
  • Does this answer your question? [Return a 2d array from a function](https://stackoverflow.com/questions/8617683/return-a-2d-array-from-a-function) – HolaYang Oct 30 '19 at 03:44
  • Two problem i can see in ur code: return type is not proper( it should be int** instead of int*) , also memory allocation has to be done for 2d array. – Pankaj Oct 30 '19 at 03:45
  • @HolaYang I am still confused by that answer. – kelbimon Oct 30 '19 at 04:06
  • @Pankaj I see about the return type, but how to do memory allocation for the 2d array? do i use the new function to do it? – kelbimon Oct 30 '19 at 04:07
  • Probably you need this: [How do I declare a 2d array in C++ using new?](https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new) – neutrino_logic Oct 30 '19 at 04:20
  • 2
    Use std::vector. Use std::vector. Use std::vector. Please, please, please use std::vector. Stop listening to people who explain how to return an array from a function. You don't need that. You don't use raw arrays in C++. – n. m. could be an AI Oct 30 '19 at 05:06
  • @kelbimon: check below solution given by paddy and javier silva... You can go with any of this option (memory allocation or use std::vector way) – Pankaj Oct 30 '19 at 06:50

3 Answers3

1

You are creating your board array in stack and that gets deleted after it goes out of scope. Also you are creating it as an array of integer pointers instead of array of integers.

What i suggest is you create it with new statement:

int* board_dead_state = new[width*height];

Then setting you initial values either use:

memset(board_dead_state, 0, width*height*sizeof(int));

or modify your for loop to:

for(int i = 0; i < height; i++){
    for(int j = 0; j < width; j++){
        int offset = i * width + j
        board_dead_state[offset]= 0;
    }
}

After you return the pointer from the function, you are responsible for deallocating it using delete[] statement.

You could make a board class to handle the allocation and deallocation when needed.

parti82
  • 165
  • 5
0

Here's how to use do it in your code:

int** boardStateDead(int width, int height){

    int** board_dead_state = new int*[height];

    for(int i = 0; i < height; i++){
        board_dead_state[i] = new int[width];
        for(int j = 0; j < width; j++){
            board_dead_state[i][j] = 0;
        }
    }
    return  board_dead_state;
}

Then you get it like this:

int** state = boardStateDead(someWidth, someHeight);

And access its element like state[i][j]. And finally, but probably, most importantly, when you're done using it, free its memory like this:

          for (int i = 0; i < height; i++)
          {
            delete[] state[i];
          }
          delete[] state;
Javier Silva Ortíz
  • 2,864
  • 1
  • 12
  • 21
  • 2
    People _must_ stop using this approach to 2D arrays. It's heavy, complex, ugly, and has poor cache locality. – paddy Oct 30 '19 at 05:09
  • Thanks for your answer! – kelbimon Oct 30 '19 at 18:31
  • @paddy When you say *must*, it looks like you're trying to have everyone do it the way you do it. And no offense, but people are free to choose and some have specific use cases not relating to your solution. As for *complexity*, your approach is more complex for a person with basic knowledge of the language. As for ugliness, that's **just pure opinion**, there's no computable formalism to define how *ugly* a piece of code is, it's just pure subjectivity. Although heaviness can be debated, I agree that yours has better cache locality. – Javier Silva Ortíz Oct 30 '19 at 18:44
  • Of course it's my opinion! I didn't intend to upset you by putting it so bluntly. The reality is that this approach is an anti-pattern. In terms of style and functionality, anti-patterns are ugly. This particular one has no place in modern C++. I certainly have no issue showing a more advanced approach -- I prefer they get the opportunity to expand their knowledge, instead of reinforce bad habits. – paddy Oct 30 '19 at 20:40
  • @paddy, I'm ok with your reasoning. But you referred badly to the other answers, to enhance the superiority of yours (which again, can be debated). What if the code were to run in an embedded device? Your approach would be overkill and considered *the* anti-pattern, and I can figure out *many* more scenarios where yours would definitely not be applicable. I'm just trying to avoid subjectivity (even if there's always some in our answers). Expand their knowledge by showing another way of doing it and saying its pros, but don't say things like *ugly*. An OS code is ugly, yet amazing! Cheers! – Javier Silva Ortíz Oct 30 '19 at 20:55
  • So, you recommend `height+1` allocations on an embedded device? I think we're done here! :) – paddy Oct 30 '19 at 21:01
  • @paddy It's not a recommendation, it's a use case scenario. Yours would be overkill in terms of final code size and speed. Also, just because there's a `new` in a `for` loop, it doesn't necessarily mean an allocation per iteration, it depends on the arch, and the compiler, and in some supercomputer builds it compiles to a batched allocation request. Plus, the `std` might not be available. But, if you don't want to have a constructive conversation, it's ok. Cheers! – Javier Silva Ortíz Oct 30 '19 at 21:14
0

I suggest you create a simple class or struct to hold your board state. Internally, use a std::vector so you don't need to worry about managing memory.

You can even overload operator[](int) to make it function like a 2D array, if you want.

#include <vector>

class Board
{
public:
    Board(int width, int height)
        : mWidth(width)
        , mHeight(height)
        , mState(width * height)
    {}

    int* operator[](int row) { return mState.data() + row * mWidth; }
    const int* operator[](int row) const { return mState.data() + row * mWidth; }

    int Width() const { return mWidth; }
    int Height() const { return mHeight; }

private:
    int mWidth, mHeight;
    std::vector<int> mState;
};

Now, simply construct it when you know what size it needs to be:

Board board(width, height);

The constructor for std::vector will initialize all the values to zero.

You could print this out by accessing it with the methods I've added:

for (int row = 0; row < board.Height(); row++)
{
    for (int col = 0; col < board.Width(); col++)
    {
        std::cout << ' ' << board[row][col];
    }
    std::cout << std::endl;
}

Or better still, make another method on the board, such as Print().

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
paddy
  • 60,864
  • 6
  • 61
  • 103