Как освободить ранее выделенную память при возникновении ошибок?

При таком объявлении функции:

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);
}

Если первый вызов base_address завершился успешно, а второй вызов asprintf () завершился неудачно, как мне полностью перейти к концу функции, чтобы безопасно освободить выделенные память?

Есть ли какой-то стандартный шаблон, как избежать утечек памяти в таких ситуациях, когда память выделяется одна за другой (и каждое выделение может завершиться сбоем) без слишком большого дублирования кода или операторов goto?

5
задан Max 20 September 2011 в 21:50
поделиться