Thread: Splitting dynamically allocated 2D arrays

  1. #1
    Registered User
    Join Date
    Jun 2014
    Posts
    1

    Splitting dynamically allocated 2D arrays

    Hi all,
    This is probably a very easy question, but it is late at night and I am very much stumped.

    I have the following dynamically allocated 2D array:

    Code:
    int num_rows = 100;
    int num_cols = 3;
        
    double **myArray= (double**)malloc( sizeof(double *) * num_rows);
    for(i = 0; i < num_rows; i++) {
        myArray[i] = (double*)malloc( sizeof(double) * num_cols);  
    }
    After sorting the array based on the values in column 1,:

    Code:
    qsort(myArray, num_rows, sizeof(myArray[0]), comp_function);
    
    int comp_function(const void* a, const void* b) {
             double **p1 = (double**)a;
             double **p2 = (double**)b;
             double *arr1 = *p1;
             double *arr2 = *p2;
    
        return arr1[0] - arr2[0];
    }
    I need to split the array into two halves so that I can pass each separately into another function that accepts a type double ** pointer.

    What is the most efficient way of splitting the array? Is it possible to keep the original double ** pointer for the first half of the array and then assign a new double ** pointer to the second half of the array?

    Thanks in advance for your help!

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by CodeNovice View Post
    I need to split the array into two halves so that I can pass each separately into another function that accepts a type double ** pointer.
    It's a 2-d array, so there is more than one way to split it in half. I'm guessing, since you have 100 rows and 3 columns, you want to split it into two 2-d arrays of 50 rows and 3 columns each. Clarifying this would be good, however. This affects how you can split it, since you are in row-major order. I will assume this type of split.
    Quote Originally Posted by CodeNovice View Post
    What is the most efficient way of splitting the array?
    You shouldn't worry about efficiency until you can prove through good, real data (such as profiling tools), that the splitting of these 2-d arrays is a serious bottleneck in your program. Premature optimization is the root of all evil. That aside, the answer to your question really depends. Do you just need to split it temporarily, in one small area of code? Or do you need to keep them as two separate 2-d arrays for a considerable duration, or to be used throughout a large portion of the program?
    Quote Originally Posted by CodeNovice View Post
    Is it possible to keep the original double ** pointer for the first half of the array and then assign a new double ** pointer to the second half of the array?
    Yes, the easy way is to "lie" and say that you have two 2-d arrays of 50 rows each:
    Code:
    int p1_num_rows = num_rows / 2;
    int p2_num_rows = num_rows - p1_n_elements;
    double **p1 = &myArray[0];
    double **p2 = &myArray[p1_num_cols];
    
    do_something(p1, p1_num_rows, num_cols);
    do_something(p2, p2_num_rows, num_cols);
    This basically fakes two separate arrays. It's fine for, say, splitting the array into different chunks to be sorted in different threads. But you must always remember that you can not call free(p2) since p2 does not point to an address returned by any alloc function (malloc/calloc/realloc). Only p1 can be freed. That is why I suggest using this for simpler stuff. In a complex program, keeping track of which sub-arrays can be freed will become complex.

    The other method, which is a little more complex on the surface, makes a lot of things easier since you can treat p1 and p2 as two completely separate, individually allocated arrays. Something like:
    Code:
    double p1_num_rows = num_rows / 2;
    double p2_num_rows = num_rows - p1_num_rows;
    double **p2;
    
    p2 = allocate p2_num_rows pointers-to-double;
    loop to copy second half of myArray into p2 -- this should be a shallow copy since you only need to move the pointer to the row data
    realloc p1 to only have p1_num_rows pointers-to-double -- make sure to use a temp pointer in case realloc fails
    A few more notes on malloc:
    1. Don't cast malloc.
    2. Don't use the type in the sizeof expression, use the variable, like
    Code:
    double **myArray= malloc(sizeof(*myArray) * num_rows);
    for(i = 0; i < num_rows; i++) {
        myArray[i] = malloc(sizeof(*myArray[i]) * num_cols);
    That way, if myArray ever changes to a float, int, char, etc, you only need to change the declaration and the malloc statements will still allocate the correct size.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 12-01-2011, 12:38 PM
  2. Dynamically Allocated arrays and MPI
    By DerekC in forum C Programming
    Replies: 3
    Last Post: 03-09-2010, 01:06 PM
  3. Structures and dynamically allocated arrays
    By Bandizzle in forum C Programming
    Replies: 7
    Last Post: 10-04-2009, 02:05 PM
  4. Dynamically allocated arrays
    By axe786 in forum C Programming
    Replies: 6
    Last Post: 12-03-2004, 01:41 AM
  5. Destructors in dynamically allocated arrays
    By frenchfry164 in forum C++ Programming
    Replies: 1
    Last Post: 11-28-2003, 11:26 PM