Search code examples
c++carduinomallocavr-gcc

Multidimensional Arrays - malloc vs new


I would like to allocate 2D array and I am considering two possibilities (avr-gcc on Arduio):

A:

int **arr = new int*[5];
for(int i = 0 ; i < 5 ; i++){
   arr[i] = new int[10];
}

B:

 int **arr = malloc(5 * sizeof(int *));
 for(int i = 0 ; i < 5 ; i++) {
    arr [i] = malloc(10* sizeof(int))
 } 

Is there any difference between A and B? Would the compiler create the same byte code in those two cases (arv-gcc)?


Solution

  • In C, you can't allocate memory by new, because there is no such thing. For C++, you may prefer new for couple of reasons such as:

    • exceptions (unless you add (std::nothrow) explicitly)
    • initializer lists (since C++11)
    • better safety as it returns pointer of proper type (specifically not void *)
    • cleaner syntax (but that is purely subjective)

    See In what cases do I use malloc and/or new? for more discussion on that matter.

    If you want to allocate a two-dimensional array and the rightmost size is known at compile-time (i.e. it is a constant expression - constexpr), then you don't need to loop over.

    New in C++

    int (*arr)[10] = new int [2][10];
    

    If you want it to be pre-set with zeros (that is, like std::calloc), then use:

    int (*arr)[10] = new int [2][10]{0}; // C++11
    int (*arr)[10] = new int [2][10]();  // C++03
    

    Just like for any arrays allocated by new[], there is a corresponding delete[] operator to free it:

    delete[] arr;
    

    Malloc in C and C++

    int (*arr)[10] = malloc(5 * sizeof(*arr));
    

    This allocates array, that is like arr[5][10] (only in sense of indices).

    To access its elements in both simply use:

    arr[a][b]
    

    To free it, you basically do:

    free(arr);
    

    In C++ you additionally need to take care of cast and possibly qualify it with std, so it's std::malloc (especially if includes cstdlib, as stdlib.h header is deprecated in C++ Standard):

    const int N = 10;
    
    int (*arr)[N] =
        static_cast<int (*)[N]>(std::malloc(5 * sizeof(*arr)));
    

    but I don't think that you will like it.