0
void matrixSetSize(double ***pMatrix, int size) {

    if (*pMatrix == NULL) { // void matrix
        *pMatrix = (double**)malloc(size * sizeof(double*));
        for (int i = 0; i < size; i++)
            *(*pMatrix + i) = (double*)malloc(size * sizeof(double));
    }
    else { // resize existing matrix
        double **pointer = (double**)realloc(*pMatrix, 2 * size * sizeof(double*));
        for(int i = 0; i < size; i++)
            pointer[i] = (double*)realloc(*(pMatrix+i), 2 * size * sizeof(double));

        for (int i = size; i < 2 * size; i++)
            pointer[i] = (double*)malloc(size * sizeof(double));

        for(int i = 0; i < size; i++)
            free(*(*pMatrix + i));
        free(*pMatrix);

        *pMatrix = pointer;
    }

}

Problem: When I try to realocate the size of the matrix, the code won't work and I don't know why. Can someone explain to me why isn't working?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Karl
  • 61
  • 4
  • 2
    You don't have a 2D array, you have a 1D array of pointers, and each pointer points to a 1D array of doubles. That's **not** a 2D array. – spectras Feb 15 '19 at 10:28
  • check the following link http://qa.geeksforgeeks.org/7945/reallocation-of-multidimensional-arrays-in-c.html – Papan Feb 15 '19 at 10:29
  • 2
    Whenever you feel the need to write `*(p + i)` for some pointer `p` and integer `i`, just be sensical and write `p[i]` instead. It's fewer tokens, and much easier to read (and yes I know that it could be for some pointer `i` and integer `p`, too). – unwind Feb 15 '19 at 10:35
  • The code is a mess. In order to reallocate such an "array", you need to know both the new and the old size. Currently, if you grow the array, your calls to `realloc()` on the new parts of the array will fail as the expanded portion of the outer pointer array hasn't been initialized with proper values. If you shrink the array, you will leak all the memory allocated in the portion of the pointer array removed. And the calls to `malloc()` and `free()` after the `realloc()` calls are nonsensical in their entirety. Writing code and hoping it works usually just makes things worse. – Andrew Henle Feb 15 '19 at 11:20
  • @Papan That's quite horrible code. I would strongly recommend to stay clear of trashy internet tutorials such as those posted at that site. – Lundin Feb 15 '19 at 15:05

2 Answers2

2

That does not answer your posted code's problem, but could perhaps help you for your bigger picture:

double (*matrix)[size] = malloc(initial_size * initial_size * sizeof(double));
matrix[0][0] = 42;
matrix[size-1][size-1] = 24;

/* resizing */
double (*new_mat)[new_size] = realloc(matrix, new_size*new_size*sizeof(double));
matrix[0][0] = 42;
matrix[new_size-1][new_size-1] = 24;

/* freeing */
free(new_mat);

Isn't it much simpler? And it's much, much faster to allocate/free, since it's only one allocation. And it's much, much faster to use, since:

  • it's one contiguous memory block, so it's cache-friendly
  • you directly access the cell, you don't have a data dependency on an intermediate pointer.

Please, when you want a 2D-array, make a 2D-array, not a 1D-array-to-pointers-of-N-1D-arrays.

two caveats: 1) if you want to preserve old data on resizing you need to move it manually and 2) your compiler must support C99.

spectras
  • 13,105
  • 2
  • 31
  • 53
  • 1
    More details on the topic here: [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Lundin Feb 15 '19 at 15:06
  • Oh great, I never stumbled upon that answer of yours, adding to favorites, I have to explain this so often in my development groups. – spectras Feb 15 '19 at 15:55
1

Two problems:

  1. Consider these lines from the reallocation code:

    pointer[i] = (double*)realloc(*(pMatrix+i), 2 * size * sizeof(double));
    pointer[i] = (double*)malloc(size * sizeof(double));
    

    In the second you don't allocate as much memory as the reallocation.

  2. After you have reallocated, you free the old data, but it has already been done by the realloc calls.

On an unrelated note, in C you should not cast the result of malloc (or it siblings).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621