Un puntero crudo con ownership en C++ bloquea el code review
Un puntero crudo con ownership en C++ es un bug que bloquea el review. No es un detalle de estilo ni un "lo limpiamos después": es un bloqueador. La gestión manual de memoria sin un wrapper es exactamente donde se esconden los leaks, los double free y los use-after-free, y además es la señal más fácil de aplicar mecánicamente: si un T* es dueño de lo que apunta, el review se detiene hasta que deje de serlo.
Esto importa el doble ahora que los agentes de código escriben buena parte de tus diffs. Los modelos entrenados con décadas de código anterior a C++11 emiten sin problema un new en una función y un delete en otra. Tu trabajo en el review no es rastrear cada camino entre ambos: es rechazar el patrón de plano.
Por qué "ownership" es la palabra clave
Un puntero crudo en sí no es el problema. Las C++ Core Guidelines son explícitas: R.3 — un puntero crudo (un T*) no es dueño. El puntero que observa un objeto que otro posee es idiomático y de costo cero. La clase de bugs empieza en el momento en que un puntero crudo además es responsable de llamar a delete:
- Cada retorno temprano es un leak. Una excepción o un
returnolvidado entrenewydeletefuga memoria en silencio. - El ownership es invisible en el punto de llamada.
process(widget*)— ¿toma ownership? No se puede saber por la firma, así que alguien termina liberando dos veces, o nunca. - Anula el sistema de tipos. El compilador no garantiza nada sobre la vida de un
T*; ununique_ptr<T>convierte el mismo contrato en código que el compilador verifica.
Por eso la guía R.11 dice: evita llamar a new y delete explícitamente en código de aplicación.
La tabla de reemplazos
| Escribiste | Escribe en su lugar | Por qué |
|---|---|---|
T* p = new T(...) + delete p | auto p = std::make_unique<T>(...) | Ownership exclusivo, liberado en cada ruta de salida (R.20) |
| "Dos lugares lo necesitan vivo" | std::shared_ptr<T> — solo para vida realmente compartida | El conteo de referencias cuesta; R.21 dice preferir unique_ptr |
| Parámetros de puntero + longitud | std::span<T> (C++20) | Una vista no propietaria con límites (F.24 / I.13) |
| Solo mirar, nunca liberar | T*, T& o const T& | No propietario por convención (R.3, F.7) |
| Destructor/copy/move escritos a mano | Regla de cero — deja que los miembros se gestionen solos | Si cada miembro es RAII, no escribes ninguna de las cinco (C.20) |
El procedimiento de decisión cabe en una frase: unique por defecto, shared solo cuando la vida es genuinamente compartida, vistas para todo lo demás.
Trucos power-user: aplicarlo a los agentes
- Ponlo en las instrucciones del agente. Una línea en tu
CLAUDE.md/ system prompt — "Los punteros crudos con ownership están prohibidos; usaunique_ptr,shared_ptrsolo para vida compartida,span/referencias para vistas; prefiere tipos con regla de cero" — previene el patrón en lugar de cazarlo. - Convierte al toolchain en el revisor.
clang-tidyincluye checks que automatizan exactamente esto:cppcoreguidelines-owning-memorymarca punteros crudos con ownership, ymodernize-make-uniquereescribenewcomomake_unique. Conéctalos al CI para que el bloqueo sea automático, no social. - Haz grep antes de revisar.
grep -rn "new \|delete " src/sobre un diff generado por IA toma cinco segundos y atrapa a la mayoría de los infractores antes de leer una línea de lógica. - Salida de emergencia, etiquetada. La interoperabilidad con APIs de C a veces obliga a ownership crudo en la frontera. Envuélvelo de inmediato (
unique_ptrcon un deleter personalizado) y limita el alcance del handle crudo a una sola función.
La recompensa es el cierre del reel: el ownership se vuelve explícito y toda una clase de bugs deja de ser expresable. Cuando tu agente emita un puntero crudo con ownership — bloquéalo.
Recursos
- C++ Core Guidelines R.11 — Avoid calling
newanddeleteexplicitly - C++ Core Guidelines R.3 — A raw pointer (a
T*) is non-owning - C++ Core Guidelines C.20 — la regla de cero
std::unique_ptr— cppreferencestd::span— cppreference- Check
cppcoreguidelines-owning-memoryde clang-tidy
¿Construyes una funcionalidad con IA? Yeda AI diseña, audita y entrega sistemas LLM de producción.