简体   繁体   中英

Free all the space allocated for a pointer-to-pointer, without knowing its type

I have a C program which uses a few pointers such as int ** , float ** , double ** , long ** , etc. At the end, I want to free the space that was allocated for them.

To modularize things, I have a function that can take an object of the form pointer-to-pointer and free the memory space allocated for it. For instance, the following, for a variable of type int ** .

void FreeIntArray(int **A, int length){
    int i;
    for (i = 0; i < length; i ++)
       free(A[i]);
    free(A);
}

However, to free a variable of the form float ** or double ** , I need to write another function that is almost a carbon copy of the one above, except changing int ** to float ** in the function definition.

Is a way to design a single function that can free space allocated to any of the following datatypes: int ** , float ** , double ** , long ** ?

If you want to punctiliously adhere to the ISO C standard's definition of what is maximally portable, there is no way to do this without repetitive coding. We can roll the logic into a single function, but that function will need some sort of switch on an integer variable indicating the type, so it can access the type ** pointer correctly as the correct type.

We can drop maximal portability and just assume that all pointers have the same representation. (Plus the additional assumption that we won't be bitten by strict aliasing assumptions in the optimizing compiler.) Then we can write it like this:

void free_array(void *aptr, size_t nelem) {
    void **a = (void **) aptr;
    while (nelem--)
      free(*a++);
    free(aptr);
}

Another alternative is to use a macro:

#define GEN_AFREE(name, type)                   \
   void afree_ ## name (type **a, size_t nelem) \
   {                                            \
     [...]                                      \
   }

GEN_FREE_ARRAY_FUN(int, int)
GEN_FREE_ARRAY_FUN(double, double)
GEN_FREE_ARRAY_FUN(string, char)

Or instead of a defining macro, we could just make a macro that encapsulates looping over an array and calling free:

#define FREE_ARRAY(array, size) do {         \
  size_t iNdEx;                              \
  for (iNdEx = 0; iNdEx < (size); iNdEx++)   \
    free((array)[iNdEx]);                    \
  free(array);                               \
} while (0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM