Thread: De-allocation of a matrix.

  1. #1
    Registered User
    Join Date
    Apr 2013
    Posts
    122

    De-allocation of a matrix.

    Hi,
    In my text book the de-allocation of a dynamically allocated matrix is carried out thus:
    Code:
    void freeMatrix(char** mat) {
         free(mat[0]);
         free(mat);
    }
    Why is it mandatory to include free(mat[0]) and free(mat) is not enough?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Look in your textbook for the allocation of the matrix, and observe how that matches the de-allocation.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    After doing what Laserlight said and you are sure you understood, you can take a look at this example too.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  4. #4
    Registered User
    Join Date
    Jun 2013
    Posts
    66
    Quote Originally Posted by peripatein View Post
    Hi,
    In my text book the de-allocation of a dynamically allocated matrix is carried out thus:
    Code:
    void freeMatrix(char** mat) {
         free(mat[0]);
         free(mat);
    }
    Why is it mandatory to include free(mat[0]) and free(mat) is not enough?
    Depending on how the matrix is allocated, even including free(mat[0]) may not be enough. If each row (or column if allocating in column major order) is a separate call to malloc, then those calls must all be mirrored when freeing:
    Code:
    void free_matrix(char **matrix, size_t rows)
        {
        size_t i;
    
        for (i = 0; i < rows; i++)
            {
            free(matrix[i]);
            }
    
        free(matrix);
        }
    Without knowing how the matrix is allocated, it is difficult to say whether the freeMatrix function in your textbook is correct or not. Erring on the side of trust, I would say it is correct and that the matrix is allocated like so:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define ROWS 10
    #define COLS 10
    
    int main(void)
        {
        int **matrix = (int**)malloc(ROWS * sizeof *matrix);
        int *mem = (int*)malloc(COLS * ROWS * sizeof *mem);
        size_t i, j;
    
        /* Link blocks from mem to matrix */
        for (i = 0; i < ROWS; i++)
            {
            matrix[i] = mem + (i * COLS);
            }
    
        /* Use matrix just like an array */
        for (i = 0; i < ROWS; i++)
            {
            for (j = 0; j < COLS; j++)
                {
                matrix[i][j] = (int)(j * i + 1);
                }
            }
    
        for (i = 0; i < ROWS; i++)
            {
            for (j = 0; j < COLS; j++)
                {
                printf("%3d", matrix[i][j]);
                }
    
            puts("");
            }
    
        /* Correctly free all memory */
        free(matrix[0]); /* free(mem) works too */
        free(matrix);
    
        return EXIT_SUCCESS;
        }
    Notice that the number of calls to free perfectly match the number of calls to malloc.

  5. #5
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    You surely did not check the example I provided above!

    You need also to read about casting malloc.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by sonjared
    Without knowing how the matrix is allocated, it is difficult to say whether the freeMatrix function in your textbook is correct or not.
    Hence my suggestion to look at how the matrix is allocated
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jun 2013
    Posts
    66
    Quote Originally Posted by std10093 View Post
    You surely did not check the example I provided above!
    Nor do I care. Duplicated effort does not equate to wasted effort. Often different perspectives on and descriptions of the same topic help to clarify the concept.

    Quote Originally Posted by std10093 View Post
    You need also to read about casting malloc.
    I'm aware of the issues. Just be cause my choices are different from yours does not make them incorrect.

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Lol the quote of the year, Imo : "I'm aware of the issues. Just because my choices are different from yours does not make them incorrect."

  9. #9
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Obviously what sonjared said does not worth a comment (but because everyone deserves a second chance, let me inform you that the link comes from the faq ).

    As for the question, I came into a situation where I needed to write the exact same free function.

    So check the link here, I have draw a picture too, so that one can see why we need to free like this.
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  10. #10
    Registered User
    Join Date
    Jun 2013
    Posts
    66
    Quote Originally Posted by std10093 View Post
    Obviously what sonjared said does not worth a comment (but because everyone deserves a second chance, let me inform you that the link comes from the faq ).
    How kind of you to give me a second chance at continuing to be correct. Allow me to quote from the FAQ you hold in such high esteem:

    There is nothing wrong with this except in the event that stdlib.h, the header which declares malloc, is not included.
    Please note that I did not fail to include stdlib.h. This point is moot, and I was aware of that particular "problem" with casting malloc before reading your FAQ.

    Also, during maintenance, if the type of the pointer changes but the cast is not changed, once again there is a difficult to find bug.
    I have been writing code for a long time, and cannot remember encountering a single instance of this situation that was not caught by the compiler, much less lint. If one is making code changes like that without looking at warnings or de-linting the result, one gets what one deserves.

    I notice that the FAQ fails to mention C++ compatibility, which is a primary reason why I cast the result of malloc. But I also notice the trailing comment, which you seem to have neglected when trying to chastise me about my perfectly valid choice:

    However, you should use whichever you like provided you are aware of the issues.
    Is what I say worth a comment now?

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Is what I say worth a comment now?
    O_o

    No.

    o_O

    Wait...

    NOOOOOOooooo!

    Soma

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Please note that I did not fail to include stdlib.h. This point is moot, and I was aware of that particular "problem" with
    > casting malloc before reading your FAQ.
    The problem with the cast isn't when you include stdlib.h, it's when you FAIL to include stdlib.h and you've cast the result of malloc. In this case, the error (in the mis-declaration of malloc) is masked by the cast. C99 is better in this respect, since it removed the "implicit declaration rule", so not including stdlib.h in C99 is no longer an option.

    > I notice that the FAQ fails to mention C++ compatibility, which is a primary reason why I cast the result of malloc.
    If a cast of malloc were the only difference between C and C++, you might have a point.

    However, there are a whole host of differences which make most non-trivial C programs more challenging to work the same in C++ (for example all those extra C++ keywords which are valid identifiers in C - int class; anyone).
    Incompatibilities Between ISO C and ISO C++

    If you really want a C++ program, then use std::vector, or failing that, the new operator.
    Using malloc in a C++ program, on something which is a class / struct (with a constructor) is just woe compounding woe.

    You should look up Polyglots sometime. Programs valid in multiple languages are seldom good examples of programming style in any language.


    > and cannot remember encountering a single instance of this situation that was not caught by the compiler, much less lint
    You are fortunate enough to have a decent set of tools.
    However, half the people who roll into this forum (and pretty much every other forum) are still using fossil TurboC.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Jun 2013
    Posts
    66
    The problem with the cast isn't when you include stdlib.h, it's when you FAIL to include stdlib.h and you've cast the result of malloc. In this case, the error (in the mis-declaration of malloc) is masked by the cast. C99 is better in this respect, since it removed the "implicit declaration rule", so not including stdlib.h in C99 is no longer an option.
    I don't fail to include stdlib.h, so it's not my problem. If I were ever to post code that does so, you're welcome to bash me and then gloat about it, but that won't happen.

    If a cast of malloc were the only difference between C and C++, you might have a point.
    Casting malloc is one of many things I do to maintain compatibility. It appears that I mistakenly assumed this would be obvious.

    If you really want a C++ program, then use std::vector, or failing that, the new operator.
    Thus completely missing the point. Rest assured, when I want C++ and just C++, I do write C++.

    However, half the people who roll into this forum (and pretty much every other forum) are still using fossil TurboC.
    Once again, not my problem.

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Once again, not my problem.
    O_o

    Well, yeah, it is your problem; you've kind of made it a point to make it your problem by saying the problem is questionable or even imaginary.

    I have been writing code for a long time, and cannot remember encountering a single instance of this situation that was not caught by the compiler, much less lint.
    So, you have limited experience in that you've only had decent tools, but you are using that limited view to forward casting the return value from `malloc' over not casting the return value.

    Just because you've never seen tools that misses an improper cast from `malloc' doesn't mean that such don't exist and aren't unfortunately prolific.

    Soma

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Once again, not my problem.
    Even for a programmer, you're remarkably self-centred.

    This isn't about you and your wonderful set of tools, it's about informing newbies the best way(s) of getting the best results across a whole variety of tools. Outside of your perfect little world, casting malloc in C causes more harm than good.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Finding a sub-matrix in a bigger matrix
    By pashakhanloo in forum C++ Programming
    Replies: 1
    Last Post: 10-31-2012, 10:42 AM
  2. reading a matrix and printing out the matrix
    By Lina_inverse in forum C Programming
    Replies: 9
    Last Post: 10-23-2012, 04:09 PM
  3. Replies: 6
    Last Post: 05-14-2011, 09:28 AM
  4. Need help in Matrix Addition & finding Inverse of a Matrix
    By ssatyan.129 in forum C Programming
    Replies: 6
    Last Post: 05-15-2009, 02:48 PM
  5. Matrix: Reloaded + Enter The Matrix (the game)
    By LuckY in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 04-18-2003, 12:35 AM