0

Shown below is a piece of code written in C with an intention of reallocating memory inside a function. I would like to know why this crashes during execution and also an efficient way to do it.

int main()
     {
        int *kn_row, *kn_col, *uk_row, *uk_col;
        double *kn_val, *uk_val;
        kn_row=NULL, kn_col=NULL, kn_val=NULL, uk_row=NULL, uk_col=NULL, uk_val=NULL;
        evaluate_matrices(&kn_row, &kn_col, &kn_val, &uk_row, &uk_col, &uk_val);
        ........
     }

I tried with two types of function:

 evaluate_matrices(int **ptr_kn_row, int **ptr_kn_col, double **ptr_kn_val,
                   int **ptr_uk_row, int **ptr_uk_col, double **ptr_uk_val)
      {    
        ........
        /* i,j, and k are calculated */
        *ptr_kn_row=(int*)realloc(*ptr_kn_row,k*sizeof(int));
        *ptr_kn_col=(int*)realloc(*ptr_kn_col,k*sizeof(int));
        *ptr_kn_val=(double*)realloc(*ptr_kn_val,k*sizeof(double));
        /* and*/
        *ptr_uk_row=(int*)realloc(*ptr_uk_row,j*sizeof(int));
        *ptr_uk_col=(int*)realloc(*ptr_uk_col,i*sizeof(int));
        *ptr_uk_val=(double*)realloc(*ptr_uk_val,i*sizeof(double));
      }

The other way is:

evaluate_matrices(int **ptr_kn_row, int **ptr_kn_col, double **ptr_kn_val,
                  int **ptr_uk_row, int **ptr_uk_col, double **ptr_uk_val)
      {
         int *temp1,*temp2,*temp3,*temp4;
         double *temp5,*temp6;
         ..........
         temp1 =(int*)realloc(*ptr_kn_row, k*sizeof(*temp1));
         if(temp1){*ptr_kn_row = temp1;}
         temp2 =(int*)realloc(*ptr_kn_col, k*sizeof(*temp2));
         if(temp2){*ptr_kn_col = temp2;}
         temp5 =(double*) realloc(*ptr_kn_val, k*sizeof(*temp5));
         if(temp5){*ptr_kn_val = temp5;}
         ......
         temp3 = (int*)realloc(*ptr_uk_row, j*sizeof(*temp3));
         if(temp3){*ptr_uk_row = temp3;}
         temp4 = (int*)realloc(*ptr_uk_col, i*sizeof(*temp4));
         if(temp4){*ptr_uk_col = temp4;}
         temp6 = (double*)realloc(*ptr_uk_val, i*sizeof(*temp6));
         if(temp6){*ptr_uk_val = temp6;}
      }
Stoka
  • 39
  • 7
  • 1
    Are you writing C or C++? If you're writing C++, why are you using `realloc()` in the first place? I see the question mentions C explicitly — that's good. Do not double tag questions with C and C++; it gets people upset (because the correct answer for C++ is usually completely irrelevant to C). – Jonathan Leffler Jan 07 '14 at 03:35
  • @JonathanLeffler, And vice-versa :) – chris Jan 07 '14 at 03:39
  • 1
    In what way does this "fail to execute"? Can you insert some diagnostic `printf` calls and show us the output to demonstrate the problem? What kind of values (order of magnitude) do i, j and k take? – pmdj Jan 07 '14 at 03:39
  • 1
    What do you mean by "fails to execute"? That's like going to a doctor and complaining you have "symptoms". What actually happens? – user2357112 Jan 07 '14 at 03:40
  • *"fails to execute"* is awfully vague. Does it compile? does it run? Does it crash, or give incorrect results? Describe a real problem, and maybe we can help. – abelenky Jan 07 '14 at 03:40
  • @pmjordan, i,j and k ranges from 100 to 100000 – Stoka Jan 07 '14 at 03:45

2 Answers2

1

The first function is a minor disaster if memory allocation fails. It overwrites the pointer to the previously allocated space with NULL, thereby leaking the memory. If your strategy for handling out of memory is 'exit at once', this barely matters. If you were planning to release the memory, then you've lost it — bad luck.

Consequently, the second function is better. You're probably going to need to keep track of array sizes, though, so I suspect you'd do better with structures rather than raw pointers, where the structure will contain size information as well as the pointers to the allocated data. You must be able to determine how much space is allocated for each array, somehow.

You also need to keep track of which, if any, of the arrays could not be reallocated – so you don't try to access unallocated space.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

I spy with my little eye:

*ptr_kn_val=(double*)realloc(*ptr_kn_val,k*sizeof(int));
                                           ^^^^^^^^^^^

I'm sure you meant sizeof(double) and this is just a copy-paste error.

On many systems, int is smaller than double, so if that's the case on yours, this is very likely to be the cause of your crash. That is, undefined behaviour at some point after writing past the end of the memory block.

paddy
  • 60,864
  • 6
  • 61
  • 103