C++ : new, delete, excepciones, std::terminate y RAII. Asegurando liberación de recursos

แชร์
ฝัง
  • เผยแพร่เมื่อ 23 ธ.ค. 2024

ความคิดเห็น • 14

  • @diegorfuentes
    @diegorfuentes 4 ปีที่แล้ว +5

    Gracias por el vídeo. Y el Leak al final es porque si se lanza la excepción, en el catch no se hace el ptc_close();

  • @silose
    @silose 5 ปีที่แล้ว +1

    👍, Saludos.

  • @d4ny3l23
    @d4ny3l23 4 ปีที่แล้ว +5

    Hola Profe, como puedo usar Valgrind en windows ?? he buscado y no encuentro. me aria falta Valgrind para ayudarme a saber esas cosas de perdidas.

    • @ProfesorRetroman
      @ProfesorRetroman  4 ปีที่แล้ว +3

      Lo lamento, pero no puedes usar Valgrind en Windows, porque sólo es para Linux. Lo que puedes hacer es usar Valgrind a través de sistemas de emulación de Linux en Windows, como el WSL o Cygwin, pero Valgrind es de Linux. En Windows tienes que usar otros sistemas para supervisar la gestión de memoria.

  • @aibou2399
    @aibou2399 5 ปีที่แล้ว +3

    Excelente vídeo, se agradece el trabajo. Y que curioso que la librería X11 tenga leaks. ¿Eso es porque es una librerìa escrita en C, y no existe RAII en C?

    • @ProfesorRetroman
      @ProfesorRetroman  5 ปีที่แล้ว +5

      Bueno, realmente no tiene leaks. Forzamos la aparición de leaks al lanzar excepciones e impedir su cierre como es debido por la interrupción del flujo normal de ejecución. Efectivamente, se debe a que xlib está en C. No es nada muy relevante tampoco: poco más que una mera curiosidad. Si hay leaks en otras librerías más recientes y sobre todo problemas en los drivers gráficos en general. Al usar OpenGL, por ejemplo, aparecen muchos de este estilo dependiendo de los drivers que tengamos.

  • @ninfarave
    @ninfarave 2 ปีที่แล้ว +1

    🖖

  • @ninfarave
    @ninfarave 2 ปีที่แล้ว +2

    Hola. Excelente video. Tengo entendido que la excepciones de hardware. Como null access pointer, division by zero. No pueden ser capturadas con el try catch de C++. Se que es posible capturar estas interrupciones de linux/windows con EEH y transformarlas en excepciones de c++. Sin embargo esto solo funciona con gcc/msvc y no con clang. Pregunto esto por que un backend http el programa no puede caerse por este tipo de excepciones. Por que debe devolver al cliente http una repuesta, como un http 500. Y si hay otras peticiones siendo atendidas por otras hebras pues también las dejaría sin repuesta. ¿Usted tiene alguna idea de por que en clang no funcionan? ¿Será un bug? o ¿Algo de diseño?. En clang solo funciona setjmp longjmp pero no puedo convertirlas en excepciones del C++.

    • @ProfesorRetroman
      @ProfesorRetroman  2 ปีที่แล้ว +2

      Gracias por el aprecio :).
      Esto que llamas "excepciones hardware" son en realidad bugs en tu código. Tu código no debe nunca dividir por cero o desreferenciar un nullptr. Si lo hace, es un bug en tu código, no una excepción como concepto del lenguaje de C++. Esto no es propio de C++, sino común a cualquier lenguaje nativo. Si un lenguaje te permite "capturar" estos problemas, necesariamente es un lenguaje gestionado o interpretado, para poder capturarlos antes de que se ejecuten en el hardware. No es tanto por el lenguaje pues, como por su implementación. Si se hiciera una "máquina virtual de C++" también podría "capturar" esto. De hecho, eso es lo que hacen softwares como el Address Sanitizer (integrado tanto en Clang como en GCC) o Valgrind. Estos softwares introspectivos bien introducen instrumentalización del código (gestión) o simulan una máquina virtual (Valgrind) para detectar tus errores y reportártelos. Sin embargo, tampoco su intención es la de que puedas capturarlos: sólo la de que puedas conocerlos para corregirlos, pues son bugs.
      Sin embargo, no veo que sea una buena idea en absoluto intentar irse al nivel del procesador para capturar estos problemas. No es esa la forma de evitar que tu servidor http se caiga. La forma es que tu servidor no tenga bugs. Los bugs deben ser identificados y corregidos, no circunvenidos. Implementar técnicas de este estilo, además de ser un manejo directo del hardware que el SO puede no permitir, podría tener efectos laterales sobre el resto de procesos de la máquina. No es una buena práctica. Además, produciría que dejes de prestar atención a tus bugs, ya que no los verías suceder. Por otra parte, haciendo esto abrirías la puerta a la explotación de esos bugs como punto de entrada para atacantes, ya que podrían ganar acceso a la máquina a partir de estos saltos introducidos.
      Sin duda alguna, no creo que sea una buena idea en modo alguno hacer esto en un entorno de producción o con una finalidad como esta. Para estos problemas, lo lógico, es identificarlos en el ciclo de desarrollo, depurarlos y corregirlos, ya que son bugs.

    • @SLTRM
      @SLTRM 2 ปีที่แล้ว +2

      Considera usar GraalVM java native_image. Compila a nativo código máquina. Maneja mejor la excepciones para poder depurar mejor.

    • @ninfarave
      @ninfarave 2 ปีที่แล้ว

      @@SLTRM gracias por tu sugerencia, veré que hacer, la verdad solo quería reescribir un backend usando C++ pero no se ya si sea la mejor opción o no. Native Image maneja los null pointer access con try catch?

    • @SLTRM
      @SLTRM 2 ปีที่แล้ว

      @@ninfarave Si todo igual a el java de jvm. Solo que ahora es compilado a código máquina como lo hace c/c++. Puedes capturar en el catch esos errores que describes y enviarlos a herramientas como rollbar loggy sumologic y otras usando un cliente http. C# tiene otro proyecto AOT compiler, pero es un alfa y no es para producción todavía.

  • @sherpad01
    @sherpad01 3 ปีที่แล้ว +2

    Gran vídeo, tengo una pequeña duda. Dices que el caso de pasar el ancho y alto por valor para reservar la memoria para screen es más rápido que pasarlo por referencia al ser valores básicos de 32 bits. ¿En que casos conviene pasar parámetros por valor y en cuales por referencia si solo los vas a usar para lectura? Muchas gracias.

    • @ProfesorRetroman
      @ProfesorRetroman  3 ปีที่แล้ว +3

      Es una buena pregunta, y este es uno de esos casos donde siempre comento que es necesario saber lo que pasa a bajo nivel para programar bien a alto nivel. El tema de pasar por valor o referencia puede requerir a veces copiar grandes cantidades de valores (paso por valor) o simplemente dar una dirección de memoria (paso por referencia). Sin embargo, hay ocasiones en que la copia por valor cabe en los registros de la CPU, pudiendo ser más eficiente que el paso por referencia ya que la copia es más rápida que los posteriores accesos indirectos. No hay una regla general para esto: depende de la CPU y del funcionamiento de paso de valores entre funciones. Conociendo cómo funciona y cómo es tu CPU, puedes ver el ensamblador generado y entender qué opción es mejor. Aprenderse reglas no es buena idea, porque las reglas son dependientes siempre de las circunstancias: hay que entender los principios para saber valorarlo en cada situación.
      En estas situaciones concretas, cuando el tamaño del valor a pasar es igual o inferior al tamaño de un puntero en la máquina, se puede decir que suele ser mejor pasar por valor que por referencia, en cuanto a eficiencia se refiere. Pero, como te decía antes, no lo tomes como una regla. Evita siempre las reglas mnemotécnicas, trabaja para entender los detalles. Eso te permitirá poder decidir tú mismo en cada situación qué es mejor, basándote en conocimiento y no en reglas limitadas.