Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

int matrix with pointers in C - memory allocation confusion

I'm having some issues with producing an int matrix without creating memory leaks. I want to be able to make a given (global) matrix into any size dynamically via read_matrix(). But then i want to be able to free the memory later on. So in my main method the second printf should result in a bus error since it should not have any memory allocated to it. How would i go about creating this?

int**       first_matrix;
int**       second_matrix;
int**       result_matrix;

int** read_matrix(int size_x, int size_y)
{
    int** matrix;
    matrix = calloc(size_x, sizeof(int*));
    for(int i = 0;i<size_x;i++) {
        matrix[i] = calloc(size_y, sizeof(int));
    }
    for(int i = 0;i<size_x;i++) {
        for(int j = 0;j<size_y;j++) {
            matrix[i][j] = i*10+j;
        }
    }
    return matrix;
}

int main(int stackc, char** stack)
{
    first_matrix = read_matrix(10,10);
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]);
    free(*first_matrix);
    free(first_matrix);
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]);
}
like image 441
Fredrik Avatar asked Sep 19 '08 21:09

Fredrik


1 Answers

Just because the memory has been free'd doesn't mean you can't access it! Of course, it's a very bad idea to access it after it's been free'd, but that's why it works in your example.

Note that free( *first_matrix ) only free's first_matrix[0], not the other arrays. You probably want some kind of marker to signify the last array (unless you will always know when you free the outer array how many inner arrays you allocated). Something like:

int** read_matrix(int size_x, int size_y)
{
    int** matrix;
    matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr
    for(int i = 0;i<size_x;i++) {
        matrix[i] = calloc(size_y, sizeof(int));
    }
    matrix[size_x] = NULL; // set the extra ptr to NULL
    for(int i = 0;i<size_x;i++) {
        for(int j = 0;j<size_y;j++) {
            matrix[i][j] = i*10+j;
        }
    }
    return matrix;
}

Then when you're freeing them:

// keep looping until you find the NULL one
for( int i=0; first_matrix[i] != NULL; i++ ) {
    free( first_matrix[i] );
}
free( first_matrix );
like image 65
Graeme Perrow Avatar answered Nov 14 '22 23:11

Graeme Perrow