int matrix with pointers in C - memory allocation confusion

27,678

Solution 1

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 );

Solution 2

You need to free each row individually:


void free_matrix(int **matrix, int size_x)
{
    for(int i = 0; i < size_x; i++)
        free(matrix[i]);
    free(matrix);
}

Solution 3

Freeing the memory doesn't make it go away, it just means that another allocation might grab that same chunk of memory. Whatever you put in it will still be there until something else overwrites it.

Also, you're not freeing everything you allocated. You're only freeing the array of pointers and the first row. But even if you free everything correctly, you would still have the same effect.

If you want to create a "bus error" you need to point to memory that doesn't belong to your process. Why do you want to do that anyway?

Share:
27,678
Fredrik
Author by

Fredrik

Swedish Engineering Physics (MSc) graduate, programmer for 15 years. Like programming languages, type theory, Red Bull and hiking.

Updated on September 20, 2020

Comments

  • Fredrik
    Fredrik over 3 years

    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]);
    }