Pregunta

¿Hay algún consejo / trucos para encontrar referencias cíclicas de la shared_ptr?

Este es un exmaple de lo que estoy tratando de encontrar -. Lamentablemente no puedo encontrar el bucle en mi código

struct A
{
  boost::shared_ptr<C> anC;
};

struct B
{
  boost::shared_ptr<A> anA;
};

struct C
{
  boost::shared_ptr<B> anB;
};
¿Fue útil?

Solución 4

I ha usado una combinación de los puestos anteriores. He utilizado un perfilador de memoria, se acercó con algunos ciclos de sospechosos y se rompió mediante el uso de los de weak_ptr.

He utilizado el construido en la detección de fugas de memoria CRT antes, pero por desgracia, en mi caso hay varios conjuntos unitarios estáticos que no te dan desasignado hasta el módulo de descarga que creo que es después de que el ciclo de vida de los detectores de CRT. Básicamente se da un montón de spew que son falsos positivos.

Otros consejos

Me gustaría recomendar el uso Valgrind . Al apagar el proceso, se le mostrará toda memoria perdida. A menos que su parada alguna manera rompe el ciclo, los ciclos deben aparecer como memoria perdida y Valgrind le dirá dónde en su código de la memoria se asignó originalmente.

Yo estaba a cargo del diseño de un sistema de riesgo de crédito una vez (en C ++, aunque eso no es relevante). Estas cosas son realmente grandes gráficos con el riesgo asignado a los nodos. Tuvimos una heurística sencilla de encontrar si estábamos en un ciclo - si atravesamos más de 500 veces (no recuerdo la cifra exacta - era configurable), la respuesta era sí. La mayoría de los esquemas de detección de ciclo dependen de la heurística de este tipo.

He tenido problemas similares en el pasado -. Pérdidas de memoria debido a shared_ptr referencias cíclicas que no fue detectado durante meses

Tenga cuidado con los "cachés". Tengo un objeto (vamos a llamarlo "de fábrica"), que maneja artículos seleccionados ( "widgets"). Reproductores tenía la propiedad de ser A) Inmutable, y B) Tenía un shared_ptr<Factory> a su creador (a veces crea otros widgets, etc). Todo funcionaba bien, hasta que he añadido un caché de widgets para Fábrica - desde los Reproductores eran inmutables, que tenía sentido para almacenar en caché ellos, a devolver la misma cada vez Widget fue solicitada. Mi caché era un escondrijo de shared_ptr<Widget>, fugas de manera instantánea en silencio. Las correcciones son evidentes, por lo que no voy a entrar en ellos.

En última instancia yo era capaz de apoyarse en la plataforma que estaba usando para detectar este tipo de fugas de memoria de la CRT. CRT de Visual Studio cuenta con detección de fugas de memoria y presentación de informes, que He activado en mi programa de pruebas para evitar regresiones:

int main()
{
    // code code code
    // code code code

#ifdef _MSC_VER
    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
    _CrtDumpMemoryLeaks();
#endif
}

CCG probablemente tiene informes de fugas básica similar, pero no sé lo que es.

Creo que la respuesta más simple es que no es sólo en la medida punteros inteligentes puede hacer por usted:

Sugiero grabación cada vez que make un bucle, (fácil si crea los tres objetos a la vez, más complicado de lo contrario ...), y después se comprueba que el registro donde se elimina objetos / desvincular, o simplemente periódicamente si eso no es posible.

Se puede aplicar algún tipo de interfaz de depuración que devuelve una lista de shared_ptrs propiedad de este objeto. Que había necesidad de hacer esto para cada clase almacenada en un shared_ptr. Ahora usted tiene un gráfico genérico que se puede recorrer, y puede utilizar algoritmos de detección de ciclo en él. Creo algoritmo de componente fuertemente conectado de Tarjan podría funcionar para esto, pero la teoría de grafos no es mi fuerte.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top