2008-09-19 105 views
6

我在生成int矩阵时没有产生内存泄漏问题。我希望能够通过read_matrix()动态地将给定(全局)矩阵变成任意大小。但之后我希望能够在以后释放内存。所以在我的主要方法中,第二个printf应该会导致总线错误,因为它不应该分配任何内存。我将如何去创造这个?int指针在C中的矩阵 - 内存分配混淆

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

回答

9

只是因为内存已经free'd并不意味着你无法访问它!当然,这是一个非常糟糕的想法,它可以在free'd后访问它,但这就是为什么它在你的例子中有效。

请注意,free(*first_matrix)只有免费的first_matrix[0],而不是其他阵列。您可能需要某种标记来表示最后一个数组(除非您始终知道何时释放外部数组可以分配多少个内部数组)。喜欢的东西:

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

然后当你释放他们:

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

您需要单独释放每一行:


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

您不能在C中的for循环中声明变量。 – terminus 2008-09-19 21:26:56

+2

您可以在C99中使用,但是您的代码不能反向移植。 – 2008-09-19 21:59:20

0

你只释放first_matrix的第一行(或列)。写另一个像这样的函数:

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

您可能希望将矩阵变成一个结构来存储它的行数和列数。

1

释放内存不会使它消失,这只是意味着另一个分配可能会占用同一块内存。无论你放在哪里,它都会一直存在,直到其他东西被覆盖。

此外,你没有释放你分配的所有东西。你只是释放指针数组和第一行。但即使你正确地释放了一切,你仍然会有同样的效果。

如果你想创建一个“总线错误”,你需要指向不属于你的进程的内存。无论如何,你为什么要这么做?

+0

我只是想做到这一点,以表明内存是免费的,但现在知道错误在我的思维中,不能运行valgrind,因为我在OS X上,想要一种方式来看看我是否真的已经释放它 – Fredrik 2008-09-19 21:33:28

0

我推荐使用valgrind来追踪自由内存,而不是试图发生总线错误。它也有许多其他的东西。

山姆

+0

我在OS X上,所以我不能运行valgrind,否则我会:/ 你知道任何可以在mac上使用的替代方法吗? – Fredrik 2008-09-19 21:34:20

0

你得到的内存泄漏,因为你释放矩阵的第一行和列的清单,但没有1到第n行。您需要在循环中免费拨打电话。

有几个选择,但是: - 分配的sizeof(INT *)行+行的cols *的sizeof(int)的字节,并使用第一个字节的行指针。这样,你只有一块内存空闲(并且在分配器上也更容易) - 使用包含行数的结构。然后你可以完全避免行列表(保存内存)。唯一的缺点是你必须使用一个函数,一个宏或者一些杂乱的符号来解决矩阵问题。如果你使用第二个选项,你可以在任何C99编译器中使用这样的结构,并且只需要分配一个内存块(大小为numints * sizeof(int)+ sizeof(int)) :

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

你错过这里的概念,是一个为每个释放calloc,必须有一个免费的。 并且自由必须应用于从calloc传回的指针。

我建议你创建一个函数(名为delete_matrix) 使用一个循环来释放所有您在这里

为分配指针(INT I = 0;我< size_x;我++){ matrix [i] = calloc(size_y,sizeof(int)); }

然后,一旦完成,释放由此分配的指针。

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

你现在正在做的方式,

免费(* first_matrix); free(first_matrix);

不会做你想做的事情。