Pergunta

Estou tendo alguns problemas com a produção de uma matriz int sem criar vazamentos de memória. Quero poder transformar uma determinada matriz (global) em qualquer tamanho dinamicamente via read_matrix (). Mas então eu quero poder liberar a memória mais tarde. Portanto, no meu método principal, o segundo printf deve resultar em um erro de barramento, pois não deve ter nenhuma memória alocada a ele. Como eu iria criar isso?

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]);
}
Foi útil?

Solução

Só porque a memória foi livre não significa que você não pode acessar! Claro, é um muito mal A ideia de acessá -lo depois de ser gratuita, mas é por isso que funciona no seu exemplo.

Observe que free( *first_matrix ) Apenas livre's first_matrix[0], não as outras matrizes. Você provavelmente deseja que algum tipo de marcador signifique a última matriz (a menos que você sempre saiba quando libertar a matriz externa quantas matrizes internas você alocou). Algo como:

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

Então, quando você está libertando -os:

// keep looping until you find the NULL one
for( int i=0; first_matrix[i] != NULL; i++ ) {
    free( first_matrix[i] );
}
free( first_matrix );

Outras dicas

Você precisa liberar cada linha individualmente:


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

Liberar a memória não faz com que ela desapareça, apenas significa que outra alocação pode pegar o mesmo pedaço de memória. Tudo o que você colocar nele ainda estará lá até que algo mais o substitua.

Além disso, você não está liberando tudo o que alocou. Você está apenas liberando a variedade de ponteiros e a primeira linha. Mas mesmo se você libertar tudo corretamente, ainda terá o mesmo efeito.

Se você deseja criar um "erro de barramento", precisa apontar para a memória que não pertence ao seu processo. Por que você quer fazer isso de qualquer maneira?

Você só libertou a primeira linha (ou coluna) de First_Matrix. Escreva outra função como esta:

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

Você pode querer transformar a matriz em uma estrutura para armazenar sua contagem de linhas e colunas.

Eu recomendo usar o Valgrind para rastrear a memória não -adquirida, em vez de tentar fazer com que ocorra um erro de barramento. Ele arrasa para muitas outras coisas também.

Sam

Você está recebendo vazamentos de memória porque está liberando a primeira linha da matriz e a lista de linhas, mas nenhuma das linhas 1 a Nth. Você precisa ligar gratuitamente em um loop.

Existem algumas alternativas, no entanto: - alocar tamanho de (int*)linhas + linhascols*sizeof (int) bytes e use os primeiros bytes para os ponteiros da linha. Dessa forma, você só tem um único pedaço de memória para libertar (e também é mais fácil para o alocador) - use uma estrutura que contém o número de linhas. Em seguida, você pode evitar completamente a lista de linhas (salvando memória). A única desvantagem é que você precisa usar uma função, uma macro ou alguma notação confusa para abordar a matriz.

Se você for com a segunda opção, poderá usar uma estrutura como essa em qualquer compilador C99 e novamente só precisar

struct matrix {
    int rows;
    int data[0];
}

O conceito que você está perdendo aqui é que, para cada calloc, deve haver um livre. e que gratuito deve ser aplicado ao ponteiro transmitido do Calloc.

Eu recomendo que você crie uma função (chamada Delete_Matrix) que usa um loop para libertar todos os ponteiros que você alocou aqui

para (int i = 0; i <size_x; i ++) {matrix [i] = calloc (size_y, sizeof (int)); }

Então, uma vez feito, liberte o ponteiro alocado por isso.

matrix = calloc (size_x, sizeof (int*));

Do jeito que você está fazendo agora,

grátis (*primeiro_matrix); grátis (primeiro_matrix);

Não fará o que você quer fazer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top