2012-01-17 1 views
2

Вот мой код:Динамически распределения и _freeing_ двумерный массив двойной

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

#define M 5 
#define N 3 

double **create_matrix(int m, int n); 
void destroy_matrix(double **matrix, int m); 

int main(void) 
{ 
    int i = 0, j = 0; 
    int x = 0; 
    double **matrix; 

    matrix = create_matrix(M, N); 

    while (i < M) { 
    j = 0; 
    while (j < N) { 
     printf("%4.0f", *(*(matrix + j) + i) = j); 
     j++; 
    } 
    putchar('\n'); 
    i++; 
    } 

    destroy_matrix(matrix, M); 

    return 0; 
} 

double **create_matrix(int m, int n) 
{ 
    int i = 0; 
    double **matrix; 

    if ((matrix = (double **) malloc(sizeof(double *) * m)) != NULL) { 
    while (i < m) 
     if ((*(matrix + i++) = (double *) malloc(sizeof(double) * n)) == NULL) 
     return NULL; 

    return matrix; 
    } else 
    return NULL; 
} 

void destroy_matrix(double **matrix, int m) 
{ 
    int i = 0; 

    while (i < m) 
    free((void *) *(matrix + i++)); 

    free((void *) matrix); 
} 
  • Allocating, инициализация и печать матрицы работ.
  • Выделение, а не инициализация и освобождение работ.
  • Выделение, инициализация и освобождение НЕ работает.

Backtrace:

*** glibc detected *** [file]: free(): invalid next size (fast): 0x0000000001e7d040 *** 

Вслед за картой памяти.

Я искал аналогичные проблемы, но не смог найти подходящую мне ситуацию, и я не смог бы получить от них мои.

+0

Кстати, http://stackoverflow.com/questions/1733881/c-correctly-freeing-memory-of-a Многомерный массив - это точно такая же проблема, хотя, учитывая, что вы тестировали и помогали мысли, я могу понять путаницу. По крайней мере, эта ссылка содержит код, который может оказаться полезным – sirlark

+0

Не _exactly_ хотя ... без инициализации, которая, как оказалось, была проблемой. – enlightened

ответ

1

Ваши функции распределения и освобождения матрицы выглядят хорошо для меня. Но инициализация матричных элементов имеет ошибку:

while (i < M) { 
    j = 0; 
    while (j < N) { 
     printf("%4.0f", *(*(matrix + j) + i) = j); 
     j++; 
    } 
    putchar('\n'); 
    i++; 
    } 

Это выражение

*(*(matrix + j) + i)

должен быть изменен этим выражением

*(*(matrix + i) + j)

потому что i являются ваши строк и j - это ваши колонны.

Обратите внимание, что вы также можете использовать более простую форму matrix[i][j], что эквивалентно *(*(matrix + i) + j) в вашей программе.

+0

Глупо меня! Я изменил переменные цикла и перепутал ...; (Спасибо! – enlightened

+0

@enlightened приветствуется. Это очень распространенная ошибка при работе с матрицами. – ouah

0

Вы освобождаете разыменование, то есть адрес, на который указывает содержимое массива. Попробуйте это вместо этого. Обратите внимание на отсутствие «*» перед «(матрица + я ++) в строке 6

void destroy_matrix(double **matrix, int m) 
{ 
    int i = 0; 

    while (i < m) 
    free((void *) (matrix + i++)); 

    free((void *) matrix); 
} 
+0

Но если 'matrix' является указателем на массив из указатели, то, конечно, должно быть по крайней мере одно разыменование для каждой строки? – unwind

+0

указатель - целые числа, ваш '+ i ++' - это то же самое, что и матрица [i], которая является разыменованием уже – sirlark

+0

, подумайте об этом, я не могу помните, учитывается ли размер шрифта при выполнении арифметики указателя таким образом ... вам может даже понадобиться явно умножить i на sizeof (double *) – sirlark

Смежные вопросы