# Thread: De-allocation of a matrix.

1. ## 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. Look in your textbook for the allocation of the matrix, and observe how that matches the de-allocation.

3. After doing what Laserlight said and you are sure you understood, you can take a look at this example too.

4. Originally Posted by peripatein
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. You surely did not check the example I provided above!

You need also to read about casting malloc.

6. 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

7. Originally Posted by std10093
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.

Originally Posted by std10093
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. 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. 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.

10. Originally Posted by std10093
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. Is what I say worth a comment now?
O_o

No.

o_O

Wait...

NOOOOOOooooo!

Soma

12. > 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.

13. 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. 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. > 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.

Popular pages Recent additions