473,471 Members | 1,716 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

freeing a matix

Hi,

how can I free a matrix that was created with this function:

double **my_matrix(long number_of_rows, long number_of_columns){
double **matrix;
matrix = calloc(number_of_rows, sizeof(double *));
int i;
for (i = 0; i < number_of_rows; i++){
matrix[i] = calloc(number_of_columns, sizeof(double));
}
return matrix;
}
My guess was this,

void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"

Many Thanks,
Michael Goerz
Dec 1 '06 #1
10 1400
Michael Goerz wrote:
Hi,

how can I free a matrix that was created with this function:

double **my_matrix(long number_of_rows, long number_of_columns){
double **matrix;
matrix = calloc(number_of_rows, sizeof(double *));
int i;
for (i = 0; i < number_of_rows; i++){
matrix[i] = calloc(number_of_columns, sizeof(double));
}
return matrix;
}
My guess was this,

void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"

Many Thanks,
Michael Goerz
Looks right to me. Have you tried running under a debugger to watch it?
Possibly the number of rows disagrees between the allocation and the
release?
--
Bill Medland
Dec 1 '06 #2
Bill Medland wrote:
>void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"
Looks right to me. Have you tried running under a debugger to watch it?
Possibly the number of rows disagrees between the allocation and the
release?
Yeah, I think the problem was that I put a static array in one of the
matrix rows. I guess I just can't do that, can I?

int main(){
double **m = my_matrix(4,3); // create a 4x3 matrix
m[0][1] = 5.0;
double row2[] = {1.0, 2.0, 3.0, 4.0};
m[1] = row2; // leave this out, and it doesn't crash
my_free_matrix(m, 4, 3);
return 0;
}
Dec 1 '06 #3
Michael Goerz wrote:
Bill Medland wrote:
>>void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"
Looks right to me. Have you tried running under a debugger to watch it?
Possibly the number of rows disagrees between the allocation and the
release?

Yeah, I think the problem was that I put a static array in one of the
matrix rows. I guess I just can't do that, can I?
Um, No, you can't :-)
int main(){
double **m = my_matrix(4,3); // create a 4x3 matrix
m[0][1] = 5.0;
double row2[] = {1.0, 2.0, 3.0, 4.0};
m[1] = row2; // leave this out, and it doesn't crash
my_free_matrix(m, 4, 3);
return 0;
}
Basically with C you need to understand pointers and what they point to.

m is a pointer. It points to the first element of the array. Each element
of that array is itself a pointer to the first element of an array.

What you did was to allocate all the space you needed and then change the
pointer that was the second pointer in the top level array.

Then when you went to deallocate the matrix two things happened;
a. my_free_matrix tried to release that array on the stack (which it didn't
like doing)
b. my_free_matrix did NOT try and release the space you allocated (because
you dropped the pointer to it).

What you should have done is copy the elements of row2 into the space
pointed to by m[1].

Hopefully that helps.

--
Bill Medland
Dec 1 '06 #4
I'd write this as

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
ptr = (double **)malloc(number_of_rows * sizeof(double *) +
number_of_rows * number_of_columns * sizeof(double));

temp = (double *)&ptr[number_of_rows]; /* get a pointer to where the
doubles are stored */

for (i = 0; i < number_of_rows; i++)
{
ptr[i] = &temp[i*number_of_columns];
}

return ptr;
}
Then it only takes a single free to delete it.
And you can insert rows with an assignment to a static array without
error.
Michael Goerz wrote:
Hi,

how can I free a matrix that was created with this function:

double **my_matrix(long number_of_rows, long number_of_columns){
double **matrix;
matrix = calloc(number_of_rows, sizeof(double *));
int i;
for (i = 0; i < number_of_rows; i++){
matrix[i] = calloc(number_of_columns, sizeof(double));
}
return matrix;
}
My guess was this,

void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"

Many Thanks,
Michael Goerz
Dec 3 '06 #5
I'd write this as

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
ptr = (double **)malloc(number_of_rows * sizeof(double *) +
number_of_rows * number_of_columns * sizeof(double));

temp = (double *)&ptr[number_of_rows]; /* get a pointer to where the
doubles are stored */

for (i = 0; i < number_of_rows; i++)
{
ptr[i] = &temp[i*number_of_columns];
}

return ptr;
}
Then it only takes a single free to delete it.
And you can insert rows with an assignment to a static array without
error.
Michael Goerz wrote:
Hi,

how can I free a matrix that was created with this function:

double **my_matrix(long number_of_rows, long number_of_columns){
double **matrix;
matrix = calloc(number_of_rows, sizeof(double *));
int i;
for (i = 0; i < number_of_rows; i++){
matrix[i] = calloc(number_of_columns, sizeof(double));
}
return matrix;
}
My guess was this,

void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"

Many Thanks,
Michael Goerz
Dec 3 '06 #6
Michael Goerz wrote:
Bill Medland wrote:
>>void my_free_matrix(double **m, long number_of_rows, long
number_of_columns){
int row;
for (row = 0; row < number_of_rows; row++){
free(m[row]);
}
free(m);
}

but it fails with "*** glibc detected *** double free or corruption
(out): 0xbfbbaa58 ***"
Looks right to me. Have you tried running under a debugger to watch it?
Possibly the number of rows disagrees between the allocation and the
release?

Yeah, I think the problem was that I put a static array in one of the
matrix rows. I guess I just can't do that, can I?
You can do that, but you need to keep track of which rows need freeing
and which don't.
int main(){
double **m = my_matrix(4,3); // create a 4x3 matrix
m[0][1] = 5.0;
double row2[] = {1.0, 2.0, 3.0, 4.0};
m[1] = row2; // leave this out, and it doesn't crash
my_free_matrix(m, 4, 3);
return 0;
}
Try this:

void my_free_matrix(double **m, long number_of_rows,
long number_of_columns, char *dont_free) {
int row;
for (row = 0; row < number_of_rows; row++){
if(!dont_free[row]) free(m[row]);
}
free(m);
}

int main() {
char *dont_free = calloc(4, sizeof *dont_free);
double **m = my_matrix(4, 3);
m[0][1] = 5.0;
double row2[] = {1.0, 2.0, 3.0};
dont_free[1] = 1; // register row 1 as no free
free(m[1]); // do free here to avoid mem leak
m[1] = row2;
my_free_matrix(m, 4, 3, dont_free);
free(dont_free);
return 0;
}

Note that this code, and your my_matrix function should really check for
failure of calloc; it returns a null pointer if the memory is not available.

--
Simon.
Dec 3 '06 #7
On 2 Dec 2006 18:39:31 -0800, "Samuel Stearley" <ny****@gmail.com>
wrote:
>I'd write this as

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
ptr = (double **)malloc(number_of_rows * sizeof(double *) +
number_of_rows * number_of_columns * sizeof(double));

temp = (double *)&ptr[number_of_rows]; /* get a pointer to where the
doubles are stored */
On a system where sizeof(double*) is 4, sizeof(double) is 8, and each
is required to be aligned to a multiple of its size, this is
guaranteed to fail when number_of_rows is odd.
Remove del for email
Dec 3 '06 #8
Oops

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long alignment;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
alignment = number_of_rows &1;
ptr = (double **)malloc( (number_of_rows + alignment) * sizeof(double
*) +
number_of_rows * number_of_columns * sizeof(double));

temp = (double *)&ptr[number_of_rows + alignment]; /* get a pointer to
where the
doubles are stored */

for (i = 0; i < number_of_rows; i++)
{
ptr[i] = &temp[i*number_of_columns];
}

return ptr;

}


Barry Schwarz wrote:
On 2 Dec 2006 18:39:31 -0800, "Samuel Stearley" <ny****@gmail.com>
wrote:
I'd write this as

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
ptr = (double **)malloc(number_of_rows * sizeof(double *) +
number_of_rows * number_of_columns * sizeof(double));

temp = (double *)&ptr[number_of_rows]; /* get a pointer to where the
doubles are stored */

On a system where sizeof(double*) is 4, sizeof(double) is 8, and each
is required to be aligned to a multiple of its size, this is
guaranteed to fail when number_of_rows is odd.
Remove del for email
Dec 3 '06 #9
Samuel Stearley wrote:
>
Oops

double ** my_matrix(long number_of_rows, long number_of_columns){
Are we still doing this problem?

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>

double **my_matrix(unsigned rows, unsigned columns);
void my_free_matrix(double **m, unsigned rows);
void init_matrix(double **m, unsigned rows, unsigned columns);
void show_matrix(double **m, unsigned rows, unsigned columns);

int main(void)
{
unsigned rows = 5;
unsigned columns = 7;
double **matrix;

matrix = my_matrix(rows, columns);
if (matrix != NULL) {
init_matrix(matrix, rows, columns);
show_matrix(matrix, rows, columns);
my_free_matrix(matrix, rows);
puts("\nThe matrix has been freed.");
} else {
puts("matrix == NULL");
}
return 0;
}

double **my_matrix(unsigned rows, unsigned columns)
{
double **matrix;
unsigned i;

matrix = calloc(rows, sizeof *matrix);
if (matrix != NULL) {
for (i = 0; i != rows; ++i) {
matrix[i] = calloc(columns, sizeof *matrix[i]);
if (matrix[i] == NULL) {
my_free_matrix(matrix, i);
matrix = NULL;
break;
}
}
}
return matrix;
}

void my_free_matrix(double **m, unsigned rows)
{
while (rows-- != 0) {
free(m[rows]);
}
free(m);
}

void init_matrix(double **m, unsigned rows, unsigned columns)
{
unsigned r, c;

for (r = 0; r != rows; ++r) {
for (c = 0; c != columns; ++c) {
m[r][c] = r + c + 0.5;
}
}
}

void show_matrix(double **m, unsigned rows, unsigned columns)
{
unsigned r, c;

for (r = 0; r != rows; ++r) {
for (c = 0; c != columns; ++c) {
printf("%f ", m[r][c]);
}
putchar('\n');
}
}

/* END new.c */


--
pete
Dec 4 '06 #10
On 3 Dec 2006 15:49:50 -0800, "Samuel Stearley" <ny****@gmail.com>
wrote:
>Oops

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long alignment;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
alignment = number_of_rows &1;
ptr = (double **)malloc( (number_of_rows + alignment) * sizeof(double
*) +
number_of_rows * number_of_columns * sizeof(double));
This probably solves the problem for when sizeof(double) is twice the
sizeof(double*) but now when the ratio is four (4 bytes for a pointer
and 16 bytes for a double). It just introduces a thoroughly
unnecessary lack of portability.
>
temp = (double *)&ptr[number_of_rows + alignment]; /* get a pointer to
where the
doubles are stored */

for (i = 0; i < number_of_rows; i++)
{
ptr[i] = &temp[i*number_of_columns];
}

return ptr;

}


Barry Schwarz wrote:
>On 2 Dec 2006 18:39:31 -0800, "Samuel Stearley" <ny****@gmail.com>
wrote:
>I'd write this as

double ** my_matrix(long number_of_rows, long number_of_columns){
double ** ptr;
double * temp;
long i;

/* All data is in a single malloc. First are the pointers, then the
doubles */
ptr = (double **)malloc(number_of_rows * sizeof(double *) +
number_of_rows * number_of_columns * sizeof(double));

temp = (double *)&ptr[number_of_rows]; /* get a pointer to where the
doubles are stored */

On a system where sizeof(double*) is 4, sizeof(double) is 8, and each
is required to be aligned to a multiple of its size, this is
guaranteed to fail when number_of_rows is odd.
Remove del for email

Remove del for email
Dec 4 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: disco | last post by:
I am working on this example from a book "C Primer Plus" by Prata 4th edition - p. 672. There is no erata on this problem at the publisher's website. 1) Is it a violation of copyright laws to...
11
by: Rodrigo Dominguez | last post by:
there are sometimes that I use third party libraries, I use some functions that returns char * or structs, etc. sometimes the memory that is returned by those libraries, when I try to free this...
6
by: Fernando Cacciola | last post by:
Help me out here please: While watching Brad Abraham's MSDN TV talk about the Dispose pattern, refering to: public virtual void Dispose ( bool disposing ) { if ( disposing ) { <-- WHAT...
4
by: Atul Sureka | last post by:
Hi, I want to free the object memory in C# - like we do using 'delete' keyword in C++. Lets say I have an object of some class and I want to explicitly free the memory. C# do not have any free...
5
by: Amogh | last post by:
Hi, My question is related to setting freed pointers to NULL. After freeing a pointer: 1) Should the freeing routine also be responsible for setting the pointer to null? 2) Or, should the...
3
by: billq | last post by:
Hello, I am new to c# and have become confused about freeing resources. I need to know if using an objects Dispose method does the same thing as setting the object to null? Pen bluePen = new...
9
by: david | last post by:
I will past only two segments from the code it should be enough to see what I did wrong, I think I know there I made a mistake, but how to fix it I can not tell. This why I need help from you all....
11
by: vivek | last post by:
Hello, I have a pointer to a main structure which again consists of structures, enums, char, int, float and again complex structures. When i free all the contents of the main structure, it...
25
by: Andreas Eibach | last post by:
Hi again, one of the other big woes I'm having... typedef struct perBlockStru /* (structure) Long words per block */ { unsigned long *lword; } lwperBlockStru_t;
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.