Hipster1206
Hipster1206

Reputation: 421

How to check if a pointer has been freed

I am a beginner in C. Below is my scenario - I have created a pointer variable in main function and it has been passed on to several functions(in this example 2 levels). And one of the functions frees it up. Now I need to have check in Main to see whether the pointer is freed or not, that means i need to setup the value of &str in main() to point to NULL. Not sure my approach is right here. Any help would be much appreciated

void func2(char *str)   
{
    free(str); 
}

void func1(char *str)
{
   func2(str); 
}

int main()
{ 
   char *str;
   str=(char *) malloc(10);
   func1(str);
   if(str){ do something; }  // if condition to check whether str is freed 
}

Upvotes: 4

Views: 6753

Answers (5)

SD.
SD.

Reputation: 1500

#include <stdio.h>
#include <stdlib.h>

void func2(char **str)
{
    printf("%d %s\n",__LINE__,__func__);
    free(*str);
    *str = NULL;
}

void func1(char **str)
{
    printf("%d %s\n",__LINE__,__func__);
    func2(str);
}

char * allocaMem(char **ptr)
{
    *ptr=(char *) malloc(sizeof(char)* 10);
    if(!*ptr)
    {
        perror("");
    }
    else
    {
        return *ptr;
    }
}

int main()
{
    char *str = allocaMem(&str);
    if (!str) {
        printf("Error in malloc()\n");
        return -1;
    }

    func1(&str);

    if (str) {
        printf("Memory Not freed\n");
    } else {
        printf("Memory freed\n");
    }
}

Upvotes: 0

cup
cup

Reputation: 8257

You could try something like this - first redefine malloc and free (track.h)

#ifndef track_h
#define track_h
extern void* trackmalloc(size_t size);
extern void trackfree(void* array);
extern void trackismalloc(void* array);
#define malloc trackmalloc
#define free trackfree

#endif

Then for every piece of code that uses malloc and free, replace #include with #include "track.h"

#include <stdlib.h>
#include <stdio.h>
#include "track.h" /* was <malloc.h> */

// A function which has a 20% chance of freeing the pointer
void twentypercent(char* array)
{
    if (rand() < (RAND_MAX / 5))
        free(array);
}


int main(int argc, char* argv[])
{
    char* list = malloc(256);
    int ii;

    for (ii = 0; ii < 10; ++ii)
        twentypercent(list);

    if (trackismalloc(list)
        printf("Not freed yet");

    return 0;
}

Now define track.c. This will only free memory that has been allocated by by trackmalloc. If it was not allocated by trackmalloc, then it will report that the memory has already been freed.

#include <stdio.h>
#include <malloc.h>
#define TRACKER_MAX 2048
static void* tracker[TRACKER_MAX] = { 0 };
static int track_last = -1;
void* trackmalloc(size_t size)
{
    // For simplicity, tracker will not be reused
    tracker[++track_last] = malloc(size);
    return tracker[track_last];
}

void trackfree(void* array)
{
    // This will slow down as the list gets filled up.
    // You will need a more efficient way of searching lists (possibly bsearch)
    int tt;
    for (tt = 0; tt < track_last; ++tt)
    {
        if (array == tracker[tt])
        {
            free(tracker[tt]);
            tracker[tt] = 0;
            break;
        }
    }

    if (tt == track_last)
        printf("%p already freed\n", array);
}

int trackismalloc(void* array)
{
    // This will slow down as the list gets filled up.
    // You will need a more efficient way of searching lists (possibly bsearch)
    int tt, result = 0;
    for (tt = 0; tt < track_last; ++tt)
    {
        if (array == tracker[tt])
        {
            result = 1;
            break;
        }
    }
    return result;
}

Upvotes: 1

Jeyaram
Jeyaram

Reputation: 9474

#include <stdio.h>
#include <stdlib.h>

func2(char **str)
{
        free(*str);                //free
        *str = NULL;               //Set to NULL
}

func1(char **str)                   //func1 receives as **
{
        func2(str);                //Pass pointer to func2()
}

int main()
{
        char *str = NULL;
        str=(char *) malloc(10);
        func1(&str);                //Pass Address of pointer to func1()

        if(str)                     //Check for NULL
        {
                printf("\n Not - Freed...\n");
        }
        else
        {
                printf("\n Freed...\n");
        }                                             
        return 0;
}

In C all are pass by value. I suggest to study http://www.cs.fsu.edu/~myers/cgs4406/notes/pointers.html for understanding of this.

Upvotes: 2

nightshade
nightshade

Reputation: 638

void func2(char **str)   
{
    free(*str); 
    *str = 0;
}

void func1(char **str)
{
   func2(str); 
}

int main()
{ 
   char *str;
   // I'd recommend using sizeof(type_you_want) * amount_of_elements instead of
   // a constant number: ->  malloc(sizeof(char) * 10);

   str=(char *) malloc(10);

   func1(&str); // You must pass the address of the pointer, because you want
               // to change "WHAT IT POINTS TO", not "WHAT IS POINTED BY IT"

   if(str){ do something; }  // if condition to check whether str is freed 
}

When you call a function in C, you pass a copy of those arguments, so you are passing a copy of that pointer (that copy still points to the same place, so you can change that place that it points to) but you want to change the pointer value, so you need to pass its address.

I have explained a little bit how pointers inside functions can be used in here

Upvotes: 0

Christopher C. S. Ke
Christopher C. S. Ke

Reputation: 265

void func1(char** str) {
    free(*str);
    *str = NULL;
}

void func2(char** str) {
    free(*str);
    *str = NULL;
}

int main() {
    char *str;

    str = (char*) malloc(10);
    func1(&str);
    if (str) {
        do something;
    }
}

Upvotes: 0

Related Questions