dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: dynamic allocation of 2D array

  1. #1
    Join Date
    May 2009
    Location
    Boston
    Posts
    340

    dynamic allocation of 2D array

    Hello,

    I am doing some matrix operations where I would rather not use a vector<vector<double>> and so I'm trying to work with a 2D array of double. Since the size of the matrix needs to vary, I need to dynamically allocate the array size and don't quite remember the syntax.

    I believe that for an array I would do,
    Code:
    // size of array
    unsigned int dimension = 4;
    
    // declare pointer to a double
    double *array_1;
    
    // allocate a block of memory the size of dimension*double
    // and initialize the pointer to point to  the start of the allocated block
    array_1 = (double  *) malloc( sizeof(double) * dimension );
    For a two dimensional array, I have worked out that it will look something like this,
    Code:
    // store the number of rows and columns (this is a square matrix)
    unsigned int rows = 4, columns = 4;
    
    // declare a pointer to a pointer of double
    double **a_matrix;
    
    // allocate memory for each row, a_matrix is an array of pointers
    // each of which will point to the start of an array allocated for a matrix row
    a_matrix = (double **) malloc( sizeof(double*) * rows );
    
    // loop iterator
    unsigned int i;
    
    // allocate memory for each column
    for(i=0; i<rows; i++) { a_matrix[i] = (double (*)) malloc( sizeof(double) * columns ); }
    I am not sure this is quite right. Even if it is right, I'm not entirely sure what the line for column memory allocation is actually doing. This does compile but I'm not convinced as of yet.

    I think you can also do this with new() instead of malloc() but I have never done that.

    Comments and suggestions would be appreciated.

    LMHmedchem
    Last edited by LMHmedchem; August 1st, 2018 at 12:45 AM.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,354

    Re: dynamic allocation of 2D array

    Yes, it's right - with the minor comment that (double (*)) should be just (double *). Also, if you're using C's memory functions, I would suggest you use calloc rather than malloc as calloc zero's the allocated memory. Consider

    Code:
    // store the number of rows and columns (this is a square matrix)
    unsigned int rows = 4, columns = 4;
    
    // declare a pointer to a pointer of double
    double **a_matrix;
    
    // allocate memory for each row, a_matrix is an array of pointers
    // each of which will point to the start of an array allocated for a matrix row
    a_matrix = (double **) calloc( rows, sizeof(double*) );
    
    // loop iterator
    unsigned int i;
    
    // allocate memory for each column
    for(i=0; i<rows; i++) { a_matrix[i] = (double *) calloc( columns, sizeof(double) ); }
    What this code actually does is allocate 5 1-dimenional arrays (call them A - E). The first (A) allocates a 1-dim array with the number of elements as the number of rows. The type of each element is a pointer - so the type of the pointer to this array is pointer to pointer (**). This array holds addresses for the corresponding 1-dim arrays that make up the columns (B - E). So for each of the required rows you allocate memory for the 1-dim array of columns. The columns contain the actual data so the type of this array is pointer-to (*). So array A holds pointers to the other arrays (B-E) which hold the actual data.

    When you come to access, a_matrix is of type **, so a_matrix[0] returns the contains of the first element of A which is a pointer. This can be accessed via array notation so a_matrix[0][2] gives the contents of row 0 column 2. Similarly a_matrix[1][3] gives the contents of A[1] which is a pointer to C and C[3] gives the required data.

    In c++, this would be coded as

    Code:
    // store the number of rows and columns (this is a square matrix)
    const size_t rows = 4, columns = 4;
    
    auto a_matrix = new double* [rows];
    
    // allocate memory for each column
    for (size_t i=0; i < rows; ++i) { a_matrix[i] = new double [columns]; }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.7.6)

  3. #3
    Join Date
    May 2009
    Location
    Boston
    Posts
    340

    Re: dynamic allocation of 2D array

    Thank you for the explanation, it it always helpful to see what is going on.


    Quote Originally Posted by 2kaud View Post
    In c++, this would be coded as

    Code:
    // store the number of rows and columns (this is a square matrix)
    const size_t rows = 4, columns = 4;
    
    auto a_matrix = new double* [rows];
    
    // allocate memory for each column
    for (size_t i=0; i < rows; ++i) { a_matrix[i] = new double [columns]; }
    Is there any functional difference with this approach? Why would one use one rather than the other?

    In terms of having a function return such a dynamically allocated array,

    Code:
    // declare and dynamically size a 2D array of double as pointer to pointer
    double** matrix_allocate_size(const unsigned int rows, const unsigned int columns) {
    
       // declare a pointer to a 2 dimensional array of double
       double **array_matrix;
    
       // allocate the number of rows
       array_matrix = (double **) calloc( rows, sizeof(double) );
    
       // loop iterator
       unsigned int i;
    
       // allocate space for each column of each row
       for(i=0; i<columns; i++) { array_matrix[i] = (double *) calloc( columns, sizeof(double) ); }
    
    return array_matrix;
    };
    
    // ...
    // later in the code
    // ...
    
    // call function to size array version of matrix[rows][columns]
    // this is a square matrix, so use the same dimension for rows and columns
    double **array_matrix = matrix_allocate_size(4, 4);

    or passing the 2D array to a function,
    Code:
    // print passed matrix, must also pass dimensions since they are not otherwise available
    void matrix_print(const unsigned int rows, const unsigned int columns, double **array_matrix) {
    
       // loop iterator
       unsigned int i, j;
    
       // test print matrix
       cout << "matrix data" << endl;
       for(i=0; i<rows; i++) {
          for(j=0; j<columns; j++) { cout << array_matrix[i][j] << "    "; }
          cout << endl;
       }
       cout << endl;
    
    return;
    
    // ...
    // later in the code
    // ...
    
    // call function to print matrix[rows][columns]
    // this is a square matrix, so use the same dimension for rows and columns
    matrix_print(4, 4, array_matrix);
    This looks relatively straightforward but are there any bear traps to be aware of?

    LMHmedchem

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,354

    Re: dynamic allocation of 2D array

    Why not use c++ array container? See http://www.cplusplus.com/reference/array/array/

    If you are allocating memory for a class/struct that uses constructors/destructors, the malloc/calloc and free doesn't call them when the object in memory is constructed, but new/delete does. Also new raises an exception by default if there is a problem where as malloc/calloc return NULL which has to be tested each time - which you aren't doing in the code.

    Code:
     array_matrix = (double **) calloc( rows, sizeof(double) );
    Note this should be
    Code:
     array_matrix = (double **) calloc( rows, sizeof(double*) );
    any bear traps to be aware of?
    No - just code traps! Be careful if you change the size of the array - every usage (call to function, loop etc etc) will have to be changed. Why not have 2 global consts (i know - global but consts are OK) for the column/row sizes.

    Even better, wrap it all up into a class.

    Why not do things the c++ way - instead of the c way if you're using c++?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.7.6)

  5. #5
    Join Date
    May 2009
    Location
    Boston
    Posts
    340

    Re: dynamic allocation of 2D array

    I have been trying to reply to this for a while but there appears to be something wrong with the site. Every time I click on preview, or go advanced, I get an error page. I will try again tomorrow to see if I can actually post some code.

    LMHmedchem

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)