En Windows, suponiendo que la aplicación está construida con MSVC++, puede tomar ventaja de las amplias heap debugging herramientas integradas en la depuración versión de la biblioteca estándar.
También en Windows, puede usar Application Verifier. Si recuerdo bien, tiene un modo de las fuerzas que cada asignación en una página separada con páginas de guardia protegidas en el medio. Es muy efectivo para encontrar desbordamientos de búfer, pero sospecho que también sería útil para una situación de doble liberación.
Otra cosa que podría hacer (en cualquier plataforma) habría que hacer una copia de las fuentes que se transforman (tal vez con macros) para que cada instancia de:
delete foo;
se reemplaza con:
{ delete foo; foo = nullptr; }
(Las llaves ayudan en muchos casos, aunque no son perfectas.) Eso convertirá muchas instancias de doble libre en una referencia de puntero nulo, por lo que es mucho más fácil de detectar. No atrapa todo; es posible que tenga una copia de un puntero obsoleto, pero puede ayudar a eliminar muchos de los escenarios comunes de uso después de eliminar.
No creo que haya un enfoque único para todos. En última instancia, debe rastrear cómo llegó a ser que un puntero que tenía 'delete' llamado en él todavía flotaba en uso después del hecho, lo que se reduce a rastrear la lógica de la aplicación, desafortunadamente. Puede ayudar establecer explícitamente el puntero a 'NULL' inmediatamente después de' delete', porque eso detectará otros errores de acceso a través de seg-faults. –
@Oli: Eso solo funciona si la dirección del objeto se almacena en una sola variable. Aunque lo más probable es que sea cierto en el momento en que se elimina el objeto, en los escenarios de uso después de liberación probablemente no lo sea. –
@BenVoigt: De acuerdo. –