带有指针的int矩阵C - 内存分配混乱

时间:2008-09-19 21:11:18

标签: c pointers memory-management matrix

我在生成int矩阵时遇到了一些问题而没有产生内存泄漏。我希望能够通过read_matrix()动态地将给定(全局)矩阵制作成任何大小。但后来我希望能够在以后释放内存。所以在我的main方法中,第二个printf应该导致总线错误,因为它不应该分配任何内存。我将如何创建这个?

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

7 个答案:

答案 0 :(得分:9)

仅仅因为内存已经免费并不意味着你无法访问它!当然,在它被免费后访问它是一个非常糟糕的想法,但这就是为什么它适用于你的例子。

请注意free( *first_matrix )只有free 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 );

答案 1 :(得分:2)

您需要单独释放每一行:


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

答案 2 :(得分:1)

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

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

如果要创建“总线错误”,则需要指向不属于您的进程的内存。你为什么要这样做呢?

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

萨姆

答案 5 :(得分:0)

您正在获取内存泄漏,因为您释放了矩阵的第一行和行列表,但没有释放第1行到第n行。你需要循环免费电话。

但是有几种选择: - 分配sizeof(int *) rows + rows cols * sizeof(int)bytes并使用行指针的第一个字节。这样,你只有一块内存可以释放(而且在分配器上也更容易) - 使用包含行数的结构。然后你可以完全避免行列表(节省内存)。唯一的缺点是你必须使用函数,宏或一些凌乱的符号来解决矩阵。

如果你使用第二个选项,你可以在任何C99编译器中使用这样的结构,并且只需要分配一个内存块(大小为numints * sizeof(int)+ sizeof(int)):

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

答案 6 :(得分:0)

这里缺少的概念是,对于每个calloc,必须有一个免费的。 并且必须将free应用于从calloc传回的指针。

我建议你创建一个函数(名为delete_matrix) 它使用一个循环来释放你在这里分配的所有指针

for(int i = 0; i&lt; size_x; i ++){         matrix [i] = calloc(size_y,sizeof(int));     }

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

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

你现在的方式,

<强>自由(* first_matrix);     自由(first_matrix);

不会做你想做的事。