So long as each pointer is allocated using malloc (or initialised to NULL), then that will free all the memory.
As for your other question, consider using a tool like valgrind
Eg.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( ) {
char *freed = malloc(10);
char *leaked = malloc(10);
char *broke = malloc(5);
strcpy(broke,"hello");
free(freed);
free(broke); // may or may not crash
return 0;
}
$ valgrind ./a.out
==4733== Memcheck, a memory error detector
==4733== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==4733== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4733== Command: ./a.out
==4733==
==4733== Invalid write of size 1
==4733== at 0x40269B4: memcpy (mc_replace_strmem.c:497)
==4733== by 0x80484A9: main (in /home/sc/work/a.out)
==4733== Address 0x41990ad is 0 bytes after a block of size 5 alloc'd
==4733== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==4733== by 0x8048488: main (in /home/sc/work/a.out)
==4733==
==4733==
==4733== HEAP SUMMARY:
==4733== in use at exit: 10 bytes in 1 blocks
==4733== total heap usage: 3 allocs, 2 frees, 25 bytes allocated
==4733==
==4733== LEAK SUMMARY:
==4733== definitely lost: 10 bytes in 1 blocks
==4733== indirectly lost: 0 bytes in 0 blocks
==4733== possibly lost: 0 bytes in 0 blocks
==4733== still reachable: 0 bytes in 0 blocks
==4733== suppressed: 0 bytes in 0 blocks
==4733== Rerun with --leak-check=full to see details of leaked memory
==4733==
==4733== For counts of detected and suppressed errors, rerun with: -v
==4733== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 13 from 8)