Valgrind works on unmodified executables (no need to recompile in a dedicated mode). Its oldest component, "memcheck", is key to hunting leaks, buffer overflows, uninitialized values, etc.
To execute valgrind:
valgrind executable arguments...
It will produce a summary telling how dynamically allocated memory is used when exiting the process: definitely lost, indirectly lost, possibly lost, or still reachable. Additional flags can give further details.