0

I am trying to create a simple 2D array with the size being the parameters passed by the method. In C# we would have something like this:

float[,] GenerateNoiseMap(int mapWidth, int mapHeight){
     float noiseMap[,] = new float[mapWidth, mapHeight];
     return noiseMap;
}

Any idea how I can create a 2D array and return it in C++? So far the compiler gives me an error that the size has to be a constant value, and I want the values to be what the method parameters are

1

3 Answers 3

4

I like a simple wrapper around a 1D vector:

#include <vector>

class Matrix
{
private:
    size_t rows, columns;
    std::vector<double> matrix;
public:
    Matrix(size_t numrows, size_t numcols) :
            rows(numrows), columns(numcols), matrix(rows * columns)
    {
    }

    double & operator()(size_t row, size_t column)
    {
        return matrix[row * columns + column]; // note 2D coordinates are flattened to 1D
    }

    double operator()(size_t row, size_t column) const
    {
        return matrix[row * columns + column];
    }

    size_t getRows() const
    {
        return rows;
    }
    size_t getColumns() const
    {
        return columns;
    }
};

Documentation for std::vector

Usage:

Matrix noiseMap(mapWidth, mapHeight);
Sign up to request clarification or add additional context in comments.

8 Comments

would something like: float** noiseMap = new float*[mapWidth]; for (int i = 0; i < mapWidth; ++i) noiseMap[i] = new float[mapHeight]; not be ideal?
@NathanielCutajar Every time you call new you get another block of memory. Allocating storage can be very time consuming, so the less you do, the better. Next, you have no control over where in storage this block of memory is. This ruins spatial locality and predictability of access. If the rows in your 2D array are short, you may spend orders of magnitude more time waiting for the CPU to find and load the next row than you do processing. Not as much of a problem with a single block of memory.
But what I really like about this is it is almost zero maintenance. It's almost impossible to screw it up. When you destroy Matrix, it takes all of its storage with it making it much harder to get a memory leak. With the array of arrays, you first have to delete all of the rows, then you have to delete noiseMap. Matrix you can let go out of scope and it's gone. All of it. Nice and clean.
It is also tightly contained, making it very hard to damage by accident or deliberately. You can easily add defenses like checking for out of bounds access since you only need to make edits in two functions. With the array of arrays, someone could delete noiseMap[4]; or accidentally set a row to NULL, and you're always having to pass the size around with it. Plenty of extra room for error.
I will upvote this shortly. Last question. If I were to access a variable say (in C#) int myChoice = noiseMap[1,4], how would that work with the Matrix?
|
3

You cannot have a 2D C-like array with a dynamic size on both dimensions in C++. C# arrays look a bit like them, but they're not the same thing at all.

I recommend boost::multi_array for this:

#include <boost/multi_array.hpp>

boost::multi_array<float, 2> GenerateNoiseMap(int mapWidth, int mapHeight) {
    return boost::multi_array<float, 2>{boost::extents[mapWidth][mapHeight]};
}

2 Comments

please note that i am using unreal engine to create this project, so ideally there would be a class that is already built in
@NathanielCutajar I'm not familiar with UE, but strangely enough my own search did not turn up anything.
1
float ** create_matrix(size_t m, size_t n)
{
    float ** answer = new float*[m];
    for (size_t i =0; i < m; i++)
        answer[i] = new float[n];
    return answer;
}

1 Comment

That is actually not a 2d array, but an array of (pointers to) arrays. It has quite a few drawbacks, e.g., non-continous memory, and you need to make sure that each array gets deallocated again.

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.