Search code examples
cmallocgsl

Allocate, free, allocate variable


I am using the GSL library to write some C code. I'm noticing some sort of inconsistency (at least from my limited knowledge of C) in allocating, freeing, and allocating a variable in my code using the GSL library. When the first allocation is inside the loop, things work just fine, e.g.

int i;
for(i=1; i < 101; i++){
  gsl_matrix * W = gsl_matrix_alloc(10,10);
  gsl_matrix_free(W);
}

In another function, I have the initial allocation before the loop,

int i;
gsl_matrix * W = gsl_matrix_alloc(10,10);
for(i=1; i < 101; i++){
  gsl_matrix_free(W);
  gsl_matrix * W = gsl_matrix_alloc(10,10);
}

and it DOES NOT work. Lastly, if I take out the gsl_matrix * in the loop, it works. E.g.

int i;
gsl_matrix * W = gsl_matrix_alloc(10,10);
for(i=1; i < 101; i++){
  gsl_matrix_free(W);
  W = gsl_matrix_alloc(10,10);
}

Does anyone have an explanation? Why does the placement of the first allocation inside or outside of the loop matter?


Solution

  • Your compiler should give you a warning with a hint to the explanation - something to the effect that variable W re-declared inside the loop hides variable W declared outside the loop.

    The reason the second loop does not work is that you are re-declaring W, instead of re-assigning it. That is why only the first iteration frees matrix W correctly; subsequent iterations free a dangling pointer, causing undefined behavior.

    Removing gsl_matrix * from the second line makes this a re-assignment, as intended, so the code works again.

    Note that W points to the last allocated matrix, which needs to be freed in order to avoid memory leaks:

    gsl_matrix * W = gsl_matrix_alloc(10,10);
    for(i=1; i < 101; i++){
        gsl_matrix_free(W);
        W = gsl_matrix_alloc(10,10); // re-assign
    }
    gsl_matrix_free(W); // Avoid memory leaks