'How to dynamically allocate a 2D std::array in C++ or why I should not use it?

I want to malloc an array in my code, and its size should be defined at runtime.

I tried like this:

#include <iostream>
#include <array>

int main(){
    int M=4,N=3,P=5;
    M=N+P;
    std::array<std::array<double,M>,N> arr;
}

But MSVC told me:

a variable with non-static storage duration cannot be used as a non-type argument

I don't find the answer to this in stackoverflow.(The existing question seem not to solve my problem...)

How to dynamically allocate a 2D std::array in C++?

I know I could use std::vector to solve this. But the vector memory size needs to be organized by myself and this would be used many times in my project. And I want to use C++ type code rather than C type...Maybe there is a method to turn a 2D array in C type to std::array, but I can't find it by Google...

So I ask this question...

I mean the M and N should be got dynamically(not changed,but I can only know it in runtime...),like:

#include <iostream>

int main(){
    int a=3;
    int b=4;
    int rowCount=a+b;
    int colCout=b-a;
    int** a = new int*[rowCount];
    for(int i = 0; i < rowCount; ++i)
    {
        a[i] = new int[colCount];
    }
}

I know where is my mistake. I fell into a logical question... If I don't use push_back,the vector works well. If I use it, the array doesn't work, too.

I think the capcity of vector is bigger than its size, I want to avoid this. But another question: How to limit the capacity of std::vector to the number of element show I should use my allocator or std::vector::shrink_to_fit() to avoid it...(There is no guarantee in C++17 if you use reserve(n))



Solution 1:[1]

The dynamically allocated array container in C++ is std::vector. std::array is for specifically compile-time fixed-length arrays.

https://cppreference.com is your friend!

But the vector memory size needs to be organized by myself

Not quite sure what you mean with that, but you specify the size of your std::vector using the constructor.

std::vector<std::vector<int>> arr(N);

If you need some special allocator (not just new/malloc), then you can also specify a custom allocator.

Your whole program that you propose is not good C++. A C++ solution would look like:

#include <vector>
int main() {
    int a = 3;
    int b = 4;
    unsigned int rowCount = a + b;
    unsigned int colCount = b - a;
    std::vector<std::vector<int>> matrix(rowCount);
    for (auto& row : matrix) {
        row.resize(colCount);
    }
}

Solution 2:[2]

std::array, like an actual array in C++, requires a constant size. It's what gives it any advantage at all over std::vector.

For a technical explanation as to how that requirement is implemented, remember that template parameters are required to be compile-time constants (since it changes how the code is generated, again at compile-time).

Anyway, you want to use std::vector here. If you know the size you want, give it as a constructor parameter.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Blindy