我正在编写一个C程序,该程序涉及生成随机图的邻接矩阵。以下是源代码片段:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test.h"
int main()
{
int **A = create_matrix(4, 3);
destory_matrix(A);
return 0;
}
int** create_matrix(int size, int seed)
{
// Allocate space for matrix
int **A = malloc(size * size * sizeof(int));
for (int r = 0; r < size; r++) {
A[r] = malloc(size * sizeof(int));
}
// Fill entries
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
A[i][j] = seed * (i + 1) * (j + 1);
}
}
return A;
}
void destory_matrix(int **A)
{
int size = sizeof(A[0]) / sizeof(int);
for (int r = 0; r < size; r++) {
free(A[r])
}
free(A);
}
这部分代码负责创建矩阵(create_matrix()
函数)和释放内存(destroy_matrix()
)。我在看destroy_matrix()
,注意到当传入4x4矩阵时,变量大小计算为2,而不是4。有人能解释为什么会发生这种情况吗?
我认为您对sizeof
运算符有一个基本的误解。通常,它不能用于获取动态分配的复合对象的大小。sizeof
运算符根据操作数的类型返回大小。在您的情况下,操作数的类型为int *
。我猜你运行的是64位系统。所以sizeof
的任意指针都是8。因此,无论矩阵大小如何,size
变量都将始终为2。
应用于指针的sizeof
运算符返回指针类型的大小,而不是它碰巧指向的任何已分配内存的大小。
这是C中数组类型和指针类型之间的主要区别之一(注意:数组可以衰减为指针)。应用于静态指定的数组类型(例如int foo[n];
)的sizeof
将获得以字节为单位的数组大小。
由于您的字大小可能是8字节(64位),指针的大小将是8字节,如果sizeof(int)
是4字节(32位),则8/4=2;
如果需要运行时大小的堆分配矩阵,则需要考虑其他方式来存储矩阵的维度,例如存储维度的结构和指向分配内存的指针。不过,最好完全避免可能的堆碎片。
如果你有C99:,试试这个
int n = 4, m = 5;
int (*A)[n] = malloc(m * sizeof A[0]));
free(A);
这会将int[n]
的m
长度数组分配为单个块,因此可以执行size_t n = sizeof(A)/sizeof(A[0]);
以获得一维(n
),但如果要正确迭代,则需要存储m
。