How to treat a pointer returned by malloc as a multidimensional array?

╄→гoц情女王★ 提交于 2020-03-22 09:03:31

问题


Is there a way to tell the compiler that I've allocated a memory of size N * M and I wanna treat this pointer as N * M array? In other words, is there a way to write something like this?:

int arr[N][M] = (int[N][M])malloc(N * M * sizeof(int));
arr[x][y] = 123;

I know that the compiler doesn't know the dimensions of the array, all it knows is that that's a pointer. so my question is: can I somehow tell the compiler that this pointer returned by malloc is an array pointer and it's dimensions are N * M? I can use an array to pointers, pointer to arrays or pointer to pointers, but in all cases I'll have to lookup 2 addresses. I want to have a contiguous memory on the heap and treat it as a multidimensional array. just like how I would write:

int arr[N][M];

Is there any way to achieve that?


回答1:


In a C++ program you should use the operator new.

As for malloc then in C++ M shall be a constant expression if you want to allocate a two-dimensional array.

You can write for example

int ( *arr )[M] = ( int ( * )[M] )malloc( N * M * sizeof(int) );

or

int ( *arr )[M] = ( int ( * )[M] )malloc( sizeof( int[N][M] ) );

If to use the operator new then the allocation can look like

int ( *arr )[M] = new int[N][M];

If M is not a compile-time constant then you can use the standard container std::vector as it is shown in the demonstrative program below

#include <iostream>
#include <vector>

int main() 
{
    size_t n = 10, m = 10;

    std::vector<std::vector<int>> v( n, { m } );

    return 0;
} 



回答2:


What you want is a "matrix" class like

template <typename T>
class matrix
{
    size_t len;
    size_t width;
    std::vector<T> data;
public:
    matrix(size_t len, size_t width) : len(len), width(width), data(len*width) {}
    T& operator()(size_t row, size_t col) { return data[width * row + col]; }
    const T& operator()(size_t row, size_t col) const { return data[width * row + col]; }
    size_t size() const { return len * width; }
};

int main(int argc, char const *argv[])
{
    matrix<int> m(5, 7);
    m(3, 3) = 42;
    std::cout << m(3, 3);
}

This keeps all of the data in a single contiguous buffer, and doesn't have any undefined behavior unlike all the other examples that use malloc. It's also RAII, and you don't have to write any copy or move constructors since all of the members "do the right thing" with the compiler provided defaults. You can make this class more complicated, provide a proxy object so you can overload operator[] and be able to do m[][], but at it's base this is what you want.




回答3:


If you what to avoid use of stack and you need large single block of data to keep two dimensional array of constant size (know at compile time) the this is the best cleanest way to do it:

std::vector<std::array<int, M>> arr(N);
arr[x][y] = 3;

Now if you need M is a value known at run-time, it would be best to use boost::multi_array

I do not see a reason to use malloc.




回答4:


You can do exactly what you want with a helper function. This let's you specify the array size at runtime, and it uses malloc as requested (although typically you should be using new):

#include <iostream>
#include <string>
#include <memory>

template <class T>
T** Get2DMalloc(size_t m, size_t n) {
    T** ret = (T**)malloc(sizeof(T*) * m);
    for (size_t i = 0; i < m; ++i) {
        ret[i] = (T*)malloc(sizeof(T) * n);
    }

    return ret;
}

template <class T>
void Free2D(T** arr, size_t m, size_t n) {
    for (int i = 0; i < m; ++i) {
        free(arr[i]);
    }

    free(arr);
}

int main() {
    int m = 3;
    int n = 3;

    int** a = Get2DMalloc<int>(3, 3);


    for (int x = 0; x < m; ++x) {
        for (int y = 0; y < n; ++y) {
            a[x][y] = x * m + y;
        }
    }

    for (int i = 0; i < m * n; ++i) {
        std::cout << a[i / m][i % n] << std::endl;
    }

    Free2D<int>(a, m, n);

    system("pause");
    return 0;
}


来源:https://stackoverflow.com/questions/60535539/how-to-treat-a-pointer-returned-by-malloc-as-a-multidimensional-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!