Generic function to free 2d arrays with cleanup attribute in C












1














I've recently discovered __attribute__((cleanup)) which is very handy. I have made a generic function to free any type of pointer and it works fine.



#define _autofree_ __attribute__ ((cleanup(free_pointer)))

...

void free_pointer(void *pointer)
{
free(*(void **) pointer);
}


But it's not as easy when it comes to freeing 2d arrays. As far as I know cleanup uses a pointer to the given pointer for stack restriction reasons, and it's a good thing because it doesn't use a copy of it at any point. Anyway, Dereferencing a (void **) cast to pass through "derefencing void *" errors works but then if I do



#define _autofree2d_ __attribute__ ((cleanup(free_pointer_array)))

...

void free_pointer_array(void *pointer_array)
{
for (size_t i = 0 ; (void **) pointer_array[i] ; ++i)
free(*(void **) pointer_array[i]);
free(*(void ***) pointer_array);
}


I end up dereferencing a void * because of the bracketed [i]. Also this just doesn't look right.



I'm also trying doing it in a less generic way using char pointers (as I'm currently working with a word array) and it compiles but gives we a segfault because of an invalid free.



void free_pointer_array(char ***array)
{
for (size_t i = 0 ; *array[i] ; ++i)
free(*array[i]);
free(**array); // Tried using ***array and got
// "pointer from integer without a cast" error
}









share|improve this question






















  • If you allocate an actual array, instead of an array of pointers to one-dimensional arrays, you could free the array with a single call to free(). See stackoverflow.com/questions/42094465/…
    – Andrew Henle
    Nov 20 at 20:34
















1














I've recently discovered __attribute__((cleanup)) which is very handy. I have made a generic function to free any type of pointer and it works fine.



#define _autofree_ __attribute__ ((cleanup(free_pointer)))

...

void free_pointer(void *pointer)
{
free(*(void **) pointer);
}


But it's not as easy when it comes to freeing 2d arrays. As far as I know cleanup uses a pointer to the given pointer for stack restriction reasons, and it's a good thing because it doesn't use a copy of it at any point. Anyway, Dereferencing a (void **) cast to pass through "derefencing void *" errors works but then if I do



#define _autofree2d_ __attribute__ ((cleanup(free_pointer_array)))

...

void free_pointer_array(void *pointer_array)
{
for (size_t i = 0 ; (void **) pointer_array[i] ; ++i)
free(*(void **) pointer_array[i]);
free(*(void ***) pointer_array);
}


I end up dereferencing a void * because of the bracketed [i]. Also this just doesn't look right.



I'm also trying doing it in a less generic way using char pointers (as I'm currently working with a word array) and it compiles but gives we a segfault because of an invalid free.



void free_pointer_array(char ***array)
{
for (size_t i = 0 ; *array[i] ; ++i)
free(*array[i]);
free(**array); // Tried using ***array and got
// "pointer from integer without a cast" error
}









share|improve this question






















  • If you allocate an actual array, instead of an array of pointers to one-dimensional arrays, you could free the array with a single call to free(). See stackoverflow.com/questions/42094465/…
    – Andrew Henle
    Nov 20 at 20:34














1












1








1


0





I've recently discovered __attribute__((cleanup)) which is very handy. I have made a generic function to free any type of pointer and it works fine.



#define _autofree_ __attribute__ ((cleanup(free_pointer)))

...

void free_pointer(void *pointer)
{
free(*(void **) pointer);
}


But it's not as easy when it comes to freeing 2d arrays. As far as I know cleanup uses a pointer to the given pointer for stack restriction reasons, and it's a good thing because it doesn't use a copy of it at any point. Anyway, Dereferencing a (void **) cast to pass through "derefencing void *" errors works but then if I do



#define _autofree2d_ __attribute__ ((cleanup(free_pointer_array)))

...

void free_pointer_array(void *pointer_array)
{
for (size_t i = 0 ; (void **) pointer_array[i] ; ++i)
free(*(void **) pointer_array[i]);
free(*(void ***) pointer_array);
}


I end up dereferencing a void * because of the bracketed [i]. Also this just doesn't look right.



I'm also trying doing it in a less generic way using char pointers (as I'm currently working with a word array) and it compiles but gives we a segfault because of an invalid free.



void free_pointer_array(char ***array)
{
for (size_t i = 0 ; *array[i] ; ++i)
free(*array[i]);
free(**array); // Tried using ***array and got
// "pointer from integer without a cast" error
}









share|improve this question













I've recently discovered __attribute__((cleanup)) which is very handy. I have made a generic function to free any type of pointer and it works fine.



#define _autofree_ __attribute__ ((cleanup(free_pointer)))

...

void free_pointer(void *pointer)
{
free(*(void **) pointer);
}


But it's not as easy when it comes to freeing 2d arrays. As far as I know cleanup uses a pointer to the given pointer for stack restriction reasons, and it's a good thing because it doesn't use a copy of it at any point. Anyway, Dereferencing a (void **) cast to pass through "derefencing void *" errors works but then if I do



#define _autofree2d_ __attribute__ ((cleanup(free_pointer_array)))

...

void free_pointer_array(void *pointer_array)
{
for (size_t i = 0 ; (void **) pointer_array[i] ; ++i)
free(*(void **) pointer_array[i]);
free(*(void ***) pointer_array);
}


I end up dereferencing a void * because of the bracketed [i]. Also this just doesn't look right.



I'm also trying doing it in a less generic way using char pointers (as I'm currently working with a word array) and it compiles but gives we a segfault because of an invalid free.



void free_pointer_array(char ***array)
{
for (size_t i = 0 ; *array[i] ; ++i)
free(*array[i]);
free(**array); // Tried using ***array and got
// "pointer from integer without a cast" error
}






c arrays attributes malloc free






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 at 20:24









Renard

165




165












  • If you allocate an actual array, instead of an array of pointers to one-dimensional arrays, you could free the array with a single call to free(). See stackoverflow.com/questions/42094465/…
    – Andrew Henle
    Nov 20 at 20:34


















  • If you allocate an actual array, instead of an array of pointers to one-dimensional arrays, you could free the array with a single call to free(). See stackoverflow.com/questions/42094465/…
    – Andrew Henle
    Nov 20 at 20:34
















If you allocate an actual array, instead of an array of pointers to one-dimensional arrays, you could free the array with a single call to free(). See stackoverflow.com/questions/42094465/…
– Andrew Henle
Nov 20 at 20:34




If you allocate an actual array, instead of an array of pointers to one-dimensional arrays, you could free the array with a single call to free(). See stackoverflow.com/questions/42094465/…
– Andrew Henle
Nov 20 at 20:34












1 Answer
1






active

oldest

votes


















0














As mentioned by Andrew Henle in the comments, my method of allocation was the problem. I was making a look-up table rather than an actual 2d array. Using the method described here : Correctly allocating multi-dimensional arrays, I can simply use my original _autofree_ macro for arrays of any dimension.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400980%2fgeneric-function-to-free-2d-arrays-with-cleanup-attribute-in-c%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    As mentioned by Andrew Henle in the comments, my method of allocation was the problem. I was making a look-up table rather than an actual 2d array. Using the method described here : Correctly allocating multi-dimensional arrays, I can simply use my original _autofree_ macro for arrays of any dimension.






    share|improve this answer


























      0














      As mentioned by Andrew Henle in the comments, my method of allocation was the problem. I was making a look-up table rather than an actual 2d array. Using the method described here : Correctly allocating multi-dimensional arrays, I can simply use my original _autofree_ macro for arrays of any dimension.






      share|improve this answer
























        0












        0








        0






        As mentioned by Andrew Henle in the comments, my method of allocation was the problem. I was making a look-up table rather than an actual 2d array. Using the method described here : Correctly allocating multi-dimensional arrays, I can simply use my original _autofree_ macro for arrays of any dimension.






        share|improve this answer












        As mentioned by Andrew Henle in the comments, my method of allocation was the problem. I was making a look-up table rather than an actual 2d array. Using the method described here : Correctly allocating multi-dimensional arrays, I can simply use my original _autofree_ macro for arrays of any dimension.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 at 20:02









        Renard

        165




        165






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53400980%2fgeneric-function-to-free-2d-arrays-with-cleanup-attribute-in-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            TypeError: fit_transform() missing 1 required positional argument: 'X'