问:请评论C中结构和结构分配操作的使用情况。
我正在使用BLAS和LAPACK将MATLAB程序转换成C来支持线性代数。MATLAB代码使用单元格数组。我创建了一个矩阵数据类型和一个单元数据类型。
头文件/实现的一部分:
#define ASSERT(c,m)
#define PREC double
#define ZEROS(r,c) (zeros(r,c))
#define ONES(r,c) (ones(r,c))
#define EYE(r,c) (eye(r,c))
#define ALLOCM(r,c) (alloc_matrix(r,c))
#define PRINTM(M) (print_matrix(M))
#define FREEM(M) (free_matrix(M))
#define ALLOCC(r,c) (alloc_cell(r,c))
#define GETMC(C,r,c) (get_matrix_from_cell(C,r,c))
#define SETMC(C,r,c,M) (set_matrix_in_cell(C,r,c,M))
#define FREEC(C) (free_cell(C))
/* Matrix */
typedef struct {
PREC * array;
int rows; // The number of rows in the matrix
int cols; // The number of columns in the matrix
}Matrix;
/* Cell of Matrices */
typedef struct {
Matrix * array; // Cell array of matrices stored in row major form
int rows; // Number of rows in Cell array
int cols; // Number of cols in Cell array
}Cell;
/* Matrix utility functions */
Matrix alloc_matrix(int rows, int cols);
Matrix zeros(int rows, int cols);
Matrix ones(int rows, int cols);
Matrix eye(int rows, int cols);
Matrix corrcov(Matrix matrix);
void print_matrix(Matrix matrix);
void free_matrix(Matrix matrix);
/* Cell array utility functions */
Cell alloc_cell(int rows, int cols);
INLINE Matrix get_matrix_from_cell(Cell cell, int row, int col);
INLINE void set_matrix_in_cell(Cell cell, int row, int col, Matrix matrix);
void free_cell(Cell cell);
// Implementation
Matrix
alloc_matrix(int rows, int cols){
Matrix matrix;
ASSERT(rows > 0 && cols > 0, FATAL_NEGATIVE_DIMENSIONS);
matrix.array = (PREC *) malloc(sizeof(PREC) * rows * cols);
ASSERT(matrix.array != NULL, FATAL_NO_MEMORY);
matrix.rows = rows;
matrix.cols = cols;
return matrix;
}
Matrix
zeros(int rows, int cols){
int i;
int size;
Matrix matrix;
matrix = alloc_matrix(rows, cols);
for(i = 0, size = rows * cols; i < size ; i++){
matrix.array[i] = 0.0;
}
return matrix;
}
void
print_matrix(Matrix matrix){
int i;
int j;
int k;
int rows = matrix.rows;
int cols = matrix.cols;
ASSERT(rows > 0 && cols > 0, FATAL_NEGATIVE_DIMENSIONS);
ASSERT(matrix.array != NULL, FATAL_NULL_POINTER);
printf("\n Rows: %d, Cols: %d\n", rows, cols);
for(i = 0 ; i < rows; i++){
for(j = 0, k = i * cols; j < cols; j++){
printf("%8.6f ", matrix.array[ k + j ]);
}
printf("\n");
}
}
void
free_matrix(Matrix matrix){
ASSERT(matrix.array != NULL, FATAL_NULL_POINTER);
free(matrix.array);
matrix.array = NULL;
}
Cell
alloc_cell(int rows, int cols){
Cell cell;
ASSERT(rows > 0 && cols > 0, FATAL_NEGATIVE_DIMENSIONS);
cell.array = (Matrix *) malloc(sizeof(Matrix) * rows * cols);
ASSERT(cell.array != NULL, FATAL_NO_MEMORY);
cell.rows = rows;
cell.cols = cols;
return cell;
}
void
free_cell(Cell cell){
int i;
int size;
int rows = cell.rows;
int cols = cell.cols;
ASSERT(rows > 0 && cols > 0, FATAL_NEGATIVE_DIMENSIONS);
ASSERT(cell.array != NULL, FATAL_NULL_POINTER);
for( i = 0, size = rows * cols; i < size; i++){
free_matrix(cell.array[i]);
}
free(cell.array);
}
INLINE Matrix
get_matrix_from_cell(Cell cell, int row, int col){
Matrix matrix;
int rows = cell.rows;
int cols = cell.cols;
ASSERT(cell.array != NULL, FATAL_NULL_POINTER);
ASSERT(rows > 0 && cols > 0, FATAL_NEGATIVE_DIMENSIONS);
ASSERT(row >= 0 && row < rows, FATAL_INDEX_OUT_OF_BOUNDS);
ASSERT(col >= 0 && col < cols, FATAL_INDEX_OUT_OF_BOUNDS);
matrix = cell.array[(row * cols) + col];
return matrix;
}
INLINE void
set_matrix_in_cell(Cell cell, int row, int col, Matrix matrix){
int rows = cell.rows;
int cols = cell.cols;
ASSERT(cell.array != NULL, FATAL_NULL_POINTER);
ASSERT(rows > 0 && cols > 0, FATAL_NEGATIVE_DIMENSIONS);
ASSERT(row >= 0 && row < rows, FATAL_INDEX_OUT_OF_BOUNDS);
ASSERT(col >= 0 && col < cols, FATAL_INDEX_OUT_OF_BOUNDS);
cell.array[(row * cols) + col] = matrix;
}注意,我不返回分配矩阵类型对象或单元格类型对象的函数的指针。我返回一个普通的矩阵或Cell对象,但是我在这些函数中分配数组(矩阵的PREC类型和单元格的矩阵类型--其中PREC是双倍或浮动的)。
这很方便,因为:
dot语法而不是->语法(而且,如果我使用点语法- matrix.array我 vs matrix.array->数组我,则可能只需要取消引用一次)。我分析了一个使用此接口的示例程序。
示例程序:
#include "matutil.h"
int main(){
Matrix mz;
Cell cell;
mz = ZEROS(3,3);
PRINTM(mz);
cell = ALLOCC(1,1);
SETMC(cell,0,0,mz);
PRINTM(GETMC(cell, 0 , 0));
FREEC(cell);
return 0;
}这个问题是矩阵对象(Matrix ),我从它开始,没有显式初始化它的数组字段,所以,瓦伦报告。
==17433== Conditional jump or move depends on uninitialised value(s)这是问题吗?在进行这个设计之前,我是否应该意识到有什么缺陷呢?
谢谢。
发布于 2012-02-27 10:45:58
关于
我不认为英勇警告是关于矩阵中未初始化的字段。您的zeros函数进行初始化,对吗?我用以下代码测试了自己:
Matrix zeros(int rows, int cols) {
Matrix tmp;
int i;
tmp.rows = rows;
tmp.cols = cols;
tmp.array = malloc(sizeof(float) * rows * cols);
for(i = 0; i < rows * cols; i++)
tmp.array[i] = 0;
return tmp;
}我没有英勇的警告。共享一段代码(实际上产生了val差事警告)会有帮助。
matrix->array[i]是错误的,因为->和[]都取消了指针的引用:这不会编译https://codereview.stackexchange.com/questions/9439
复制相似问题