简体   繁体   中英

C: Possible glitch in my memory deallocation function

I'm developing a small C library with functions for frequently used operations, mainly to rub up my C skills. In a session of debugging my deallocation function, i saw that the value of a pointer which previously pointed at a two-dimensional matrix isn't NULL .

I know that there is not a way to check the state of a pointer after deallocation (from reading this question), but i assigned a NULL value to this pointer to avoid it to eventually become a dangling pointer.

Function code is:

void matfree(void **M, int m){
int i;

for(i = 0; i < m; i ++){
    free(M[i]);
    M[i] = NULL;
}
free(M);
M = NULL;
}

Test code (into another file):

int matfreetest(){
int **M = NULL;

M = (int **) matmalloc(0, 2, 2);
if(*M == NULL){
    printf("Here 1! \n");
    return 0;
}
matfree(M, 2);
if(*M == NULL){
    return 1;
}
else{
    printf("Here 2! \n");
    return 0;
}
}

int main(){
int status; 

status = matmalloctest();
printf("matmalloctest status = %d \n", status);
status = matfreetest();
printf("matfreetest status = %d \n", status);
system("PAUSE");
return 1;
}

I expected matfreetest to return status 1, but it returns 0. What is done wrong here?

EDIT : Code of matmalloc, as requested:

/* Memory allocator for any type and size of matrix. 
Arguments:
-   int type:    identifier of the matrix' type
-   int m:       number of matrix rows
-   int n:       number of matrix columns
*/
void **matmalloc(int type, int m, int n){
int i;
void **M;

/* Check data type the do the proper allocation. */
if(type == INTEGER){ //int
    M = (int **) malloc(m*sizeof(int *));
    if(M == NULL){
        printf("Allocation failed! \n");
        return NULL;
    }
    for(i = 0; i < m; i ++){
        M[i] = (int *) malloc(n*sizeof(int));
        if(M[i] == NULL){
            printf("Allocation failed! \n");
            return NULL;
        }
    }
    printf("Allocation completed! \n");
    return M;
}
else if(type == SINTEGER){ //short int
    M = (short int **) malloc(m*sizeof(short int *));
    if(M == NULL){
        printf("Allocation failed! \n");
        return NULL;
    }
    for(i = 0; i < m; i ++){
        M[i] = (short int *) malloc(n*sizeof(short int));
        if(M[i] == NULL){
            printf("Allocation failed! \n");
            return NULL;
        }
    }
    printf("Allocation completed! \n");
    return M;
}
else if(type == LINTEGER){ //long int
    M = (long int **) malloc(m*sizeof(long int *));
    if(M == NULL){
        printf("Allocation failed! \n");
        return NULL;
    }
    for(i = 0; i < m; i ++){
        M[i] = (long int *) malloc(n*sizeof(long int));
        if(M[i] == NULL){
            printf("Allocation failed! \n");
            return NULL;
        }
    }
    printf("Allocation completed! \n");
    return M;
}
else if(type == FL){ //float
    M = (float **) malloc(m*sizeof(float *));
    if(M == NULL){
        printf("Allocation failed! \n");
        return NULL;
    }
    for(i = 0; i < m; i ++){
        M[i] = (float *) malloc(n*sizeof(float));
        if(M[i] == NULL){
            printf("Allocation failed! \n");
            return NULL;
        }
    }
    printf("Allocation completed! \n");
    return M;
}
else if(type == DOUB){ //double
    M = (double **) malloc(m*sizeof(double *));
    if(M == NULL){
        printf("Allocation failed! \n");
        return NULL;
    }
    for(i = 0; i < m; i ++){
        M[i] = (double *) malloc(n*sizeof(double));
        if(M[i] == NULL){
            printf("Allocation failed! \n");
            return NULL;
        }
    }
    printf("Allocation completed! \n");
    return M;
}
else if(type == LDOUB){ //long double
    M = (long double **) malloc(m*sizeof(long double *));
    if(M == NULL){
        printf("Allocation failed! \n");
        return NULL;
    }
    for(i = 0; i < m; i ++){
        M[i] = (long double *) malloc(n*sizeof(long double));
        if(M[i] == NULL){
            printf("Allocation failed! \n");
            return NULL;
        }
    }
    printf("Allocation completed! \n");
    return M;
}
else{
    printf("Incorrect type of matrix data. Only numeric types are accepted. \n");
    return NULL;
}
}

The "M" that is parameter to matfree is not the same as the one you have in the calling program. It would be better to name it differently to avoid ambiguity.

You should have:

M = matfree(M, 2); // Frees M and reassigns it to NULL

void **matfree(void **X, int m)
{
   int i;
   for(i = 0; i < m; i ++)
   {
       free(X[i]);
        X[i] = NULL;
   }
   free(X);
   return NULL;
}

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