Recursively freeing C structs

前端 未结 8 639
礼貌的吻别
礼貌的吻别 2020-12-31 23:23

I have a struct that only contains pointers to memory that I\'ve allocated. Is there a way to recursively free each element that is a pointer rather than calling free on eac

相关标签:
8条回答
  • 2020-12-31 23:53

    Not really - although you can write a method to do all six frees so that you never miss one.

    void freeModel( model* md1 ) {
        free (mdl->vertices);
        free (mdl->normals);
        free (mdl->uv_coords);
        free (mdl->quads);
        free (mdl->triangles);
        free (mdl);
    }
    
    0 讨论(0)
  • 2020-12-31 23:55

    Not with those structures. You could add another entry to your top-level 'model' struct containing a list of pointers to be freed, and iterate that list. But I doubt if the added complexity and reduced understandability of that solution would be worth it. (Unless you've got a lot bigger and more deeply-nested set of entries to free in the top-level 'model' struct than you are showing here.)

    0 讨论(0)
  • 2020-12-31 23:57

    Throw all of the free's in a function?

    0 讨论(0)
  • 2021-01-01 00:01

    You could calculate the size needed for all of them together and do one big malloc

    sizeof(model)+sizeof(vertex)*nVertices... etc.

    assign the result to mdl, result+sizeof(model) to model->vertices...

    Then to free it is just one free.

    You may have to worry about alignment issues (depending on your platform) but that shouldn't be too tough to figure out. The other problem is that it is a much larger chunk which may present a problem if in a memory constrained environment.

    0 讨论(0)
  • 2021-01-01 00:02

    Take a look at talloc http://talloc.samba.org/ if you do:

    model* mdl = talloc (NULL, ...);
    mdl->vertices = talloc (mdl, ...);
    mdl->normals = talloc (mdl, ...);
    mdl->uv_coords = talloc (mdl, ...);
    mdl->quads = talloc (mdl, ...);
    mdl->triangles = talloc (mdl, ...);
    

    you can then:

    talloc_free(mdl);
    

    and talloc will take care of free'ing all the other blocks you called talloc with mdl as the first argument at allocation time (and it will do this recursively you can do talloc(mdl->vertices, ...) and talloc_free(mdl); will get that too)

    as an aside there is a slight overhead to using talloc because it needs to track what stuff recurse over, but it's not very much.

    0 讨论(0)
  • 2021-01-01 00:04

    Such functionality is not built in to C, but you can cheat a little bit by abusing the macro preprocessor:

    #define XX_MODEL_POINTERS do { \
      xx(vertices); xx(normals); xx(uv_coords); xx(quads); xx(triangles); \
    } while(0)
    

    To allocate:

    model *mdl = malloc(sizeof(*mdl));
    assert(mdl);
    #define xx(N) mdl->N = malloc(sizeof(*mdl->N)); assert(mdl->N)
    XX_MODEL_POINTERS;
    #undef xx
    

    To free:

    assert(mdl);
    #define xx(N) free(mdl->N); mdl->NULL
    XX_MODEL_POINTERS;
    #undef xx
    free(mdl);
    mdl = NULL;
    

    The nasty bit is that the definition of struct model and the definition of XX_MODEL_POINTERS can become mutually inconsistent, and there's no way to catch it. For this reason it's often better to generate the definition of XX_MODEL_POINTERS by parsing a .h file somewhere.

    Metaprogramming in C is never easy.

    0 讨论(0)
提交回复
热议问题