I have a first-in-first-out queue implementation such that when it is first initialized, a malloc is called to set aside memory for items that will be placed on the queue. When I am done with the queue, how do I free up the memory?
My code for the queue is as follows:

typedef Edge Item;
void QUEUEinit(int);
int QUEUEempty(void);
void QUEUEput(Item);
Item QUEUEget(void);

static Item *q;
static int N,head,tail;

void QUEUEinit(int maxN)
{q = malloc((maxN+1)*sizeof(Item));
  N = maxN+1; head=N; tail=0;}

int QUEUEempty()
{ return head % N == tail;}

void QUEUEput(Item item)
{ q[tail++] = item;
  tail = tail % N;}

Item QUEUEget()
{ head = head % N;
  return q[head++];}

As defined in stdlib.h and malloc.h

free (q);

will do the trick. Assure only pointers that were created with malloc, calloc or realloc are passed to free (), otherwise other calls to get memory may have unpredictable results.

I did try the free(q), but was surprised when the following thing happened:

when there were still items on my queue, i did a free(q) and then tried to access items on my queue, it turns out that the first remaining item was not accessible but the 2nd, 3rd item so on were accessible. any explanation for this?

I did try the free(q), but was surprised when the following thing happened:

when there were still items on my queue, i did a free(q) and then tried to access items on my queue, it turns out that the first remaining item was not accessible but the 2nd, 3rd item so on were accessible. any explanation for this?

Once you've freed it, consider all of it inaccessible. If it appears that items are still accessible, that's just a temporary illusion to make you think you're doing something you're allowed to.

thanks! help appreciated.

The free() function is still puzzling me in some sense. I have a simple code below which creates a structure called graph. The code compiles without any problem and when it is executed, the output prints out 2 "10"'s, one before the free(), another one after. Did the memory set aside for G really got freed?

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

main()
{       typedef struct graph *Graph;
        struct graph{int V; int E;};

        int V=10;
        int E=10;

        Graph G=malloc(sizeof *G);
        G->V=V;
        G->E=E;

        printf("%d\n", G->E);
        free(*G);
        printf("%d\n", G->E);
        return 0;}

Apologies for my previous code....the free function should be

free(G);

I mistyped it. Any help would be greatly appreciated.

Hello,

When free() is called, a block of memory previously allocated by a call to malloc, calloc or realloc is freed:

Graph G=malloc(sizeof *G); /* Memory is dynamically allocated */
if (G != NULL) { /* G successfully points to an empty block of memory */
	/* Do task here */
}else if (G == NULL) {
	return 0; /* Memory allocation failed */
}

free(G); /* Dynamically allocated memory is freed */

Further documentation:

C Reference: malloc()
C Reference: free()


- Stack Overflow

Thanks, that's why I thought that after I "free(G)", the code

printf("%d\n", G->E);

should not be able to return me a value of 10. when it does, it surprises me, which makes me wonder whether the memory has really been freed.

Hello,

Also, be sure to set your variable to NULL after you free the memory. Example:

free(G); /* Dynamically allocated memory is freed */
G = NULL; /* This ensures that we point our pointer to NULL */

This can ensure a few things. Firstly, it ensures our pointer doesn't point to our freed address. Secondly, it secures your code from crashing if you call free() twice on the same pointer. For instance:

free(G); /* Dynamically allocated memory is freed */
free(G); /* Will cause a crash. */

Where in fact:

free(G); /* Dynamically allocated memory is freed */
G = NULL; /* This ensures that we point our pointer to NULL */
free(G); /* Won't cause a crash because G points to NULL. */

Hope this helps.


- Stack Overflow

Thanks, it does help me understand a little better. So does it mean that even though the second time I call to print (after free(G);)

printf("%d\n", G->E);

the program was able to give me 10 means that "10" is still stored at that memory but that memory is now free to be used by something else? so if I had done some other things later on in my program, and the memory storing "10" is used for something else, then I will not be able to retrieve the "10" later?

Hello,

When you call free, the memory pointed to by the passed pointer is freed, but the value of the pointer in the caller remains unchanged, because C's pass-by-value semantics mean that called functions never permanently change the values of their arguments.

A pointer value which has been freed is, strictly speaking, invalid, and any use of it, even if is not dereferenced can theoretically lead to trouble, though as a quality of implementation issue, most implementations will probably not go out of their way to generate exceptions for innocuous uses of invalid pointers.

References: ANSI Sec. 4.10.3
ISO Sec. 7.10.3
Rationale Sec. 3.2.2.3


- Stack Overflow

>so if I had done some other things later on in my program
Once freed, the memory is no longer yours. That means that in theory, another process could allocate the memory immediately after you're done freeing it and overwrite the values you had stored there before printf is called in your program. So your print isn't guaranteed to work, and on top of that, you've invoked undefined behavior because you don't own the memory you're accessing.

Great!
Thanks Stack Overflow and Narue!

Oh sorry but one more question:

If memory is allocated in the main function (via malloc), say to G, if I pass G into a function, can the memory be freed inside the function via free(G) or do I have to free(G) outside the function?

Hello,

No problem. Let me answer this question by example:

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

void test(char **p) {
	/* run test; view memory address */
	printf("Function scope: %0x%08x\n", (unsigned int)*p);
	/* free memory */
	free(*p);
	/* set to NULL */
	*p = NULL;
	printf("Function scope - After NULL: %0x%08x\n", (unsigned int)*p);
}

int main() {
	char *ptr = malloc(25);

	/* allocation may have failed */
	if (ptr == NULL)
		return 0;

	/* memory address before */
	printf("Before call: %0x%08x\n", (unsigned int)ptr);
	/* send memory address */
	test(&ptr);
	/* run some tests */
	printf("After call: %0x%08x\n", (unsigned int)ptr);

	return 0;
}

If you run this code, you will see that I passed the variables address to test(). With the address, I can modify and free the memory from within that scope. You will see that the free() and NULL calls were successful by the time we return to main().


- Stack Overflow

Really thank you for your efforts.
1) could you tell me what it means by "function scope"?
2) I was actually expecting to see the same thing (printout) for "Before call" and "Function scope (before NULL) " in the function test, but it turned out otherwise.

Hello,

1) What I mean't by function scope is simple. All it knows is what is happening within the function, and it doesn't have a clue as to what is happening in the 'int main' part of the program. This kind of scope is called 'local scope'. Whatever happens in the 'int main' is only visible to that section of the program. And on the other hand, anything that happens in the function 'test' is only visible to that part of the program, which in both cases is between the opening and closing curly braces.

2) That strikes me as well. Let me re-post my example using the %p type condition instead of the %0x%08x:

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

void test(char **p) {
	/* run test; view memory address */
	printf("Function scope: %p\n", (void *)*p);
	/* free memory */
	free(*p);
	/* set to NULL */
	*p = NULL;
	printf("Function scope - After NULL: %p\n", (void *)*p);
}

int main() {
	char *ptr = malloc(25);

	/* allocation may have failed */
	if (ptr == NULL)
		return 0;

	printf("Before call: %p\n", (void *)ptr);
	/* send memory address */
	test(&ptr);
	/* run some tests */
	printf("After call: %p\n", (void *)ptr);

	return 0;
}

In this particular case, and for testing purposes only, this is what my output looked like:

Before call: 0xa0501b8
Function scope: 0xa0501b8
Function scope - After NULL: 0x0
After call: 0x0

As seen, the address of ptr is the same when in the scope of main, and dereferenced in the scope of test().


- Stack Overflow

Yes, i got the same printout too (ie. the first two are the same while the last two are zeros), only that the values are different but that's ok since we are using differnet computers.
Guess I got it now. Really appreciate your help.
Have a good day! :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.