views:

21

answers:

2

So far I thought that the following syntax was invalid,

int B[ydim][xdim];

But today I tried and it worked! I ran it many times to make sure it did not work by chance, even valgrind didn't report any segfault or memory leak!! I am very surprised. Is it a new feature introduced in g++? I always have used 1D arrays to store matrices by indexing them with correct strides as done with A in the program below. But this new method, as with B, is so simple and elegant that I have always wanted. Is it really safe to use? See the sample program.

PS. I am compiling it with g++-4.4.3, if that matters.

#include <cstdlib>
#include <iostream>

int test(int ydim, int xdim) {
// Allocate 1D array
    int *A = new int[xdim*ydim](); // with C++ new operator
    // int *A = (int *) malloc(xdim*ydim * sizeof(int)); // or with C style malloc
    if (A == NULL)
        return EXIT_FAILURE;

// Declare a 2D array of variable size
    int B[ydim][xdim];

// populate matrices A and B
    for(int y = 0; y < ydim; y++) {
        for(int x = 0; x < xdim; x++) {
            A[y*xdim + x] = y*xdim + x;
            B[y][x] = y*xdim + x;
        }
    }

// read out matrix A
    for(int y = 0; y < ydim; y++) {
        for(int x = 0; x < xdim; x++)
            std::cout << A[y*xdim + x] << " ";
        std::cout << std::endl;
    }
    std::cout << std::endl;

// read out matrix B
    for(int y = 0; y < ydim; y++) {
        for(int x = 0; x < xdim; x++)
            std::cout << B[y][x] << " ";
        std::cout << std::endl;
    }

    delete []A;
    // free(A); // or in C style
    return EXIT_SUCCESS;
}


int main() {
    return test(5, 8);
}
+1  A: 

This is a C99 'variable length array' or VLA. If they are supported by g++ too, then I believe it is an extension of the C++ standard.

Nice, aren't they?

Jonathan Leffler
Variable length arrays are not standard C++, so it's definitely a C++ extension.
In silico
@Jon, oh yes! they are a real beauty :)
Aamir
+1  A: 

int b[ydim][xdim] is declaring a 2-d array on the stack. new, on the other hand, allocates the array on the heap.

For any non-trivial array size, it's almost certainly better to have it on the heap, lest you run yourself out of stack space, or if you want to pass the array back to something outside the current scope.

Amber
Thanks for the pointing out the caveat. Is there also a nicer way to allocate memory for multidimensional array that I am not aware of? Something as nice as, int *A = new int[xdim][ydim]();It maybe just my wishful thinking but today I totally discovered a wonder!!
Aamir
Sadly, no - though you could instead utilize the STL, which gives you things like `vector` that behave much more nicely - i.e. you can allocate `vector<vector<int>> b` and then access it as `b[x][y]`. Even if you allocated vectors on the stack, they internally generally use heap memory (only the vector *object* is stored on the stack, which keeps a pointer to the actually allocated memory).
Amber