Use malloc()
分配连续的内存块:
some_datatype_t* matrix = NULL;
matrix = malloc(nrows * ncols * sizeof(some_datatype_t));
if (!matrix) {
perror("malloc failed");
exit(ENOMEM);
}
编写一个函数来取消引用单元格:
some_datatype_t
get_value_from_matrix_at_index_ij(some_datatype_t* mtx,
uint32_t ncols,
uint32_t i,
uint32_t j)
{
return mtx[i + i * (ncols - 1) + j];
}
或者二传手:
void
set_value_for_matrix_at_index_ij(some_datatype_t** mtx_ptr,
uint32_t ncols,
uint32_t i,
uint32_t j,
some_datatype_t val)
{
*mtx_ptr[i + i * (ncols - 1) + j] = val;
}
别忘了free()
完成后你的矩阵:
free(matrix), matrix = NULL;
这是 3x4 矩阵的示例:
0 1 2 3
------------
0 | 0 1 2 3
1 | 4 5 6 7
2 | 8 9 10 11
它有 3 行和 4 列(ncols
= 4
).
在线性化形式下,其单元格如下所示:
0 1 2 3 4 5 6 7 8 9 10 11
在某个零索引行查找单元格的内容i
和列j
,您可以在常数时间内计算要取消引用的索引或地址:
{1, 2} = matrix[1 + 1*3 + 2] = matrix[6]
{2, 3} = matrix[2 + 2*3 + 3] = matrix[11]
etc.
如果您想将一些有用的属性隐藏到一个干净的包中,您甚至可以将其中的大部分包装到一个struct
:
typedef struct matrix {
some_datatype_t* data;
uint32_t nrows;
uint32_t ncols;
} matrix_t;
然后你只需初始化并传递一个指向matrix_t
多变的:
matrix_t*
init_matrix(uint32_t nrows, uint32_t ncols)
{
matrix_t *m = NULL;
m = malloc(sizeof(matrix_t));
if (!m) { /* error */ }
m->data = NULL;
m->data = malloc(nrows * ncols * sizeof(some_datatype_t));
if (!m->data) { /* error */ }
m->nrows = nrows;
m->ncols = ncols;
return m;
}
some_datatype_t
get_value_from_matrix_at_index_ij(matrix_t* mtx,
uint32_t i,
uint32_t j)
{
return mtx->data[i + i * (mtx->ncols - 1) + j];
}
void
set_value_for_matrix_at_index_ij(matrix_t** mtx_ptr,
uint32_t i,
uint32_t j,
some_datatype_t val)
{
(*mtx_ptr)->data[i + i * ((*mtx_ptr)->ncols - 1) + j] = val;
}
void
delete_matrix(matrix_t** m)
{
free((*m)->data), (*m)->data = NULL;
free(*m), *m = NULL;
}
如果您使用对称方阵,则可以利用对称性并使用一半的内存。有时,如果可以删除对角线的存储(例如,相关性或其他对称统计分数),则占用的内存会少于一半。
主要是,这里的想法是思考如何编写一个在矩阵索引对之间映射的方程(i, j)
和一些连续数组索引k
.