dado una declaración de la función así:¿Cómo liberar memoria previamente asignada cuando ocurrieron errores?
int base_address(zval *object, int add_prefix, char **base_address TSRMLS_DC) {
int result;
char *host;
long port;
char *prefix;
host = ... get host from object ...;
port = ... get port from object ...;
prefix = ... get prefix from object ...;
result = SUCCESS;
if (asprintf(base_address, "%s:%ld/%s", host, port, prefix) < 0) {
result = FAILURE;
}
return result;
}
void my_func() {
char *base_address;
char *ping_url;
if (base_address(getThis(), 0, &base_address TSRMLS_CC) == FAILURE) {
MALLOC_ERROR();
}
if (asprintf(&ping_url, "%s/ping", base_address) < 0) {
MALLOC_ERROR();
}
... do some stuff with base address ...
// release both, as everything worked
free(base_address);
free(ping_url);
}
Si la primera llamada a base_address tuvo éxito y la segunda llamada a asprintf() falló, ¿cómo limpiamente saltar al final de la función con el fin de liberar asignado de forma segura ¿memoria?
¿Hay algún patrón estándar para evitar fugas de memoria en estas situaciones en las que la memoria se asigna una tras otra (y cada asignación puede fallar) sin demasiada duplicación de código o declaraciones goto?
Goto es su amigo aquí –
¿Qué hay de malo en Goto? Podrías usar un constructo do while (0), pero eso es esencialmente lo mismo. – Luke
¿Qué hay de RAII? – Dani