0

Imagine that I have this code, my question is if in the realloc_str() function is it necessary to make an aux pointer so that I can free the content of the struct if the realloc fails. Could it be done in main()?

typedef enum { ERROR = 0, OK = 1 } STATUS;
typedef struct _str {
    int *a;
} Str;

Str *new_str() {
    Str *s = (Str *)malloc(sizeof(Str));
    if (!s) {
        return NULL;
    }
    s->a = (int *)malloc(sizeof(int) * 1);
    if (!s->a) {
        return NULL;
    }  
    return s;
}

STATUS realloc_str(Str *s, int a) {
    if (!s->a||!s) {
        return ERROR;
    }
    //this is what I mean if it is necessary to make an aux pointer to make a control of errors
    int *aux = s->a;
    s->a = (int *)realloc(s->a,sizeof(int) * a);
    if (!s->a) {
        //could this free(aux) be done in main()?
        //is this necessary?
        free(aux);
        return ERROR;
    }
    return OK;
}

int main() {
    Str *s = new_str();
    if (!s) {
        free(s);
        return ERROR;
    }
    if (realloc_str(s, 2) == ERROR) {
        free(s);
        return ERROR;
    }

    free(s);
    free(s->a);
    return 0;
}
Elparaguas
  • 27
  • 5
  • The question isn't clear. 1. Yes you need an auxiliary pointer to have a copy of original allocated space address if `realloc()` fails. If not you'll never access anymore that space and memory is waste. 2. Where free old space is your choice, locally as in your example or in `main()` before to `free()` the whole structure. Freeing a structure holding pointer to dynamically allocated memory doesn't free also that memory. – Frankie_C Apr 23 '22 at 15:39
  • No, no structs used on that question – Elparaguas Apr 23 '22 at 15:39
  • @Frankie_C so if realloc returns Null it doesn´t free old memory and you have to do it manually, right? – Elparaguas Apr 23 '22 at 15:40
  • the paradigm you show is correct. You should assign the results of `realloc` to a temp pointer. That way, if `realloc` fails, you still have your pointer to the original block, avoiding a leak. How you handle that error is entirely up to you. You can `free` the original block and quit, keep using the original block and `free` it later.. whatever you want. – yano Apr 23 '22 at 15:41
  • "No structs in that question"? _What_ you're allocating space for is inconsequential. The proper use of `realloc` is what's important. Or perhaps I'm misunderstanding your point. – yano Apr 23 '22 at 15:43
  • No a `realloc()` that fails **don't free old memory**, that's why you need the copy to use in your `free()`. – Frankie_C Apr 23 '22 at 15:43
  • @Frankie_C so if the aux pointer isn´t used to free the content of the struct if realloc fails, the code is incorrect because the new pointer (null pointer) would be overwritting the old memory, isn´t it? – Elparaguas Apr 23 '22 at 15:44
  • The behavior of `realloc()` does not depend if you use it or not in a structure. It is independent behavior. – Frankie_C Apr 23 '22 at 15:44
  • From the [`realloc` man page](https://linux.die.net/man/3/realloc): "If realloc() fails the original block is left untouched; it is not freed or moved.". So your original block is left in tact. That's why you shouldn't blindly assign `realloc` return value to the original block. If `realloc` fails, your original pointer is now NULL, losing the pointer to the original block. – yano Apr 23 '22 at 15:44
  • No. when `realloc()` fails it returns `NULL`, **but previous allocated memory continues to exist**. If you don't save a copy of old address you don't know how to free it. – Frankie_C Apr 23 '22 at 15:46
  • @yano you are right, sorry I have confused. Thanks – Elparaguas Apr 23 '22 at 15:47
  • No worries, glad you got it sorted out! – yano Apr 23 '22 at 15:52

0 Answers0