¿Me gustaría saber si es posible detectar el delete
error comentado a continuación en el momento de la compilación? Especialmente, me gustaría escuchar sobre el compilador de g ++.
ClassTypeA *abc_ptr = new ClassTypeA[100];
abc_ptr[10].data_ = 1;
delete abc_ptr; // error, should be delete []
c++
compiler
error-detection
SebGR
fuente
fuente
std::unique_ptr<ClassTypeA[]>
y luego no necesita hacerlo.Respuestas:
En general, el compilador no puede detectar tales errores. Ejemplo: supongamos que el constructor de alguna clase asigna algún miembro de datos usando
new TypeName[]
, pero el destructor usa erróneamente endelete
lugar dedelete[]
. Si el constructor y el destructor se definen en unidades de compilación separadas, ¿cómo debe saber el compilador al compilar el archivo que define el destructor que el uso es inconsistente con el del archivo compilado por separado que define el constructor?Con respecto a los compiladores de GNU, no lo hace. Como se señaló anteriormente, no puede hacerlo en el caso general. Un compilador no tiene que detectar tales errores nuevos / eliminar no coincidentes porque este es un comportamiento indefinido. UB es la tarjeta de "salir de la cárcel" del proveedor del compilador.
Herramientas como valgrind pueden detectar y detectan este tipo de desajustes nuevos / eliminar, pero lo hacen en tiempo de ejecución. Puede haber una herramienta de análisis estático que observe todos los archivos fuente que eventualmente se compilarán para formar un ejecutable, pero no conozco ninguna herramienta de análisis estático que detecte este tipo de error.
fuente
Puede usar las clases RAII apropiadas para
delete
. Esta es la única forma segura de hacerlo, y este error es solo uno de los muchos que encontrarás llamándote adelete
ti mismo.Utilice siempre clases para administrar recursos dinámicos de por vida, y el sistema de tipos impondrá la destrucción correcta de recursos.
Editar: "¿Qué sucede si está auditando el código y no puede cambiarlo?" Estas jodido
fuente
Este error particular, sí. Este tipo de error generalmente: desafortunadamente, no! Eso implicaría predecir el flujo de ejecución sin ejecutarlo realmente, y eso no es posible para programas arbitrarios. (Es por eso que la mayoría de los compiladores ni siquiera intentan detectar casos simples como su ejemplo).
Por lo tanto, la respuesta de DeadMG es la adecuada: no intente hacerlo bien prestando atención: la atención humana es falible. Use los medios proporcionados por el idioma y deje que la computadora preste atención.
fuente
ClassTypeA*
para que pueda insertar una línea entre el nuevo y el borradoif ( rand() % 2 == 1 ) abc_ptr = new ClassTypeA;
Nada en el sistema de tipo estático muestra siabc_ptr
apunta a una matriz o un objeto dinámico o parcialmente en otro objeto o matriz.abc_ptr
, de lo contrario, ¿cómo podría ser capaz de desasignar la cantidad correcta de memoria? Por lo tanto, el tiempo de ejecución sabe cuántos objetos se deben desasignar.El caso trivial que muestra puede detectarse en tiempo de compilación, porque la creación de instancias y la destrucción del objeto están en el mismo ámbito. En general, la eliminación no está en el mismo alcance, o incluso en el mismo archivo fuente, que la instanciación. Y el tipo de puntero de C ++ no contiene información sobre si hace referencia a un solo objeto de su tipo o una matriz, y mucho menos el esquema de asignación. Por lo tanto, no es posible diagnosticar esto en tiempo de compilación en general.
¿Por qué no diagnosticar los casos especiales que son posibles?
En C ++ ya hay herramientas para lidiar con la fuga de recursos dinámicos que están vinculados a ámbitos, a saber, punteros inteligentes y matrices de nivel superior (
std::vector
).Incluso si usa el
delete
sabor correcto , su código aún no es salvo para excepciones. Si el código entrenew[]
ydelete[]
termina con una salida dinámica, la eliminación nunca se ejecuta.En cuanto a la detección en tiempo de ejecución, la
Valgrind
herramienta hace un buen trabajo al detectar esto en tiempo de ejecución. Reloj:Por supuesto, Valgrind no se ejecuta en todas las plataformas, y no siempre es práctico o posible reproducir todas las situaciones de tiempo de ejecución bajo la herramienta.
fuente
Algunos ejemplos triviales de detección en tiempo de compilación / tiempo de análisis estático:
En un host RHEL7 con
cppcheck 1.77 and 1.49
http://cppcheck.sourceforge.net/
Con
clang++ 3.7.1
en RHEL7El analizador estático de Clang también puede detectar cuándo
std::unique_ptr
no se pasa<char[]>
https://clang-analyzer.llvm.org/
Actualice a continuación con un enlace al trabajo que agregó esto al sonido, las pruebas y un error que encontré.
Esto se agregó a clang con reviews.llvm.org/D4661 - "Detectar usos" nuevos "y" eliminar "que no coinciden" .
Las pruebas están en prueba / Análisis / MismatchedDeallocator-checker-test.mm
Encontré este error abierto: bugs.llvm.org/show_bug.cgi?id=24819
fuente