'How to dynamically allocate a contiguous 2D array in C++?

I need a 2d character array for use in a trash API that absolutely requires use of arrays and NOT vectors (much emphasis on this because all of my searching just had answers "use a vector". I wish I could).

I figured the way to do it would be to allocate an external array of size rows * character length, instead of doing:

char** arr;
arr = new char*[100];
// for loop that allocates the internal arrays

But I'm not sure what method I would need to use to make it contiguous? Do I need to allocate a massive 1D array first, then assign the 1D array to the 2D array in chunks?



Solution 1:[1]

This is a good way to do it:

void array2d(int m, int n) {
    std::vector<char>  bytes(m * n);
    std::vector<char*> arrays;
    for (int i = 0; i != m * n; i += n) {
        arrays.push_back(bytes.data() + i);
    }
    char** array2d = arrays.data();
    // whatever
}

Solution 2:[2]

The main problem in C++ with "continuous 2d arrays with variable column length" is that an access like myArray[r][c] requires the compiler to know the column size of the type of myArray at compile time (unlike C, C++ does not support variable length arrays (VLAs)).

To overcome this, you could allocate a continuous block of characters, and additionally create an array of pointers, where each pointer points to the begin of a row. With such a "view", you can then address the continuous block of memory indirectly with a myArray[r][c]-notation:

int main() {

    // variable nr of rows/columns:
    int rows = 2;
    int columns = 5;

    // allocate continuous block of memory
    char *contingousMemoryBlock = new char[rows*columns];

    // for demonstration purpose, fill in some content
    for (int i=0; i<rows*columns; i++) {
        contingousMemoryBlock[i] = '0' + i;
    }

    // make an array of pointers as a 2d-"view" of the memory block:
    char **arr2d= new char*[rows];
    for (int r=0; r<rows;r++) {
        arr2d[r] = contingousMemoryBlock + r*columns;
    }

    // access the continuous memory block as a 2d-array:
    for (int r=0; r<rows; r++) {
        for (int c=0; c<columns; c++) {
            cout << arr2d[r][c];
        }
        cout << endl;
    }
}

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 Charles
Solution 2