[英]Printing a matrix causes a segmentation fault
我试图根据这段代码打印一个矩阵,但不知何故它导致了分段错误。 我想将给定的 arrays 传输到结构成员数据,然后通过引用数据打印出来。 我扫描了它,但找不到我的错误。 也许我在为结构分配 memory 时搞砸了。
#include "base.h"
struct Matrix {
int rows; // number of rows
int cols; // number of columns
double** data; // a pointer to an array of n_rows pointers to rows; a row is an array of n_cols doubles
};
typedef struct Matrix Matrix;
Matrix* make_matrix(int n_rows, int n_cols) {
Matrix* mat = xcalloc(n_rows,sizeof(double*));
mat->rows = n_rows;
mat->cols = n_cols;
return mat;
}
Matrix* copy_matrix(double* data, int n_rows, int n_cols) {
Matrix* mat = make_matrix(n_rows, n_cols);
for(int i = 0; i < (mat->rows); i++)
{
for(int j = 0; j < (mat->cols); j++)
{
mat->data[i][j] = data[i] + j;
}
}
return mat;
}
void print_matrix(Matrix* m)
{
for(int i = 0; i < (m->rows); i++)
{
for(int j = 0; j < (m->cols); j++)
{
printf("%g", m->data[i][j]);
}
}
}
void matrix_test(void) {
double a[] = {
1, 2, 3,
4, 5, 6,
7, 8, 9 };
Matrix* m1 = copy_matrix(a, 3, 3);
print_matrix(m1);
double a2[] = {
1, 2, 3,
4, 5, 6 };
Matrix* m2 = copy_matrix(a2, 2, 3);
print_matrix(m2);
double a3[] = {
1, 2,
3, 4,
5, 6 };
Matrix* m3 = copy_matrix(a3, 3, 2);
print_matrix(m3);
}
在这个特定的示例中,没有明显的理由说明您应该动态分配结构本身,因为它只有 3 个项目。 因为这是完全错误的:
Matrix* mat = xcalloc(n_rows,sizeof(double*));
要么必须分别为结构及其指针数组分配空间,要么可以跳过结构的动态分配,然后只为数据成员分配空间。
此外xcalloc(n_rows,sizeof(double*));
只为指针数组分配空间,而不是那些指针指向的空间。 因此,您还需要在单独的循环中为每个数据项分配空间。
此外,对矩阵使用指针数组几乎可以肯定是不必要的晦涩和低效的做法。 相反,您应该使用二维数组,如下所示: Correctly allocating multi-dimensional arrays
您还应该 free() 所有分配的 memory。
这是一个清理过的示例,其中我将指向指针的指针替换为所谓的“灵活数组成员”。 这具有将结构与数据一起分配以加快访问速度的优点。 分散分配的所有问题也将消失。
不利的一面是灵活的数组成员必须被视为平面一维数组,因此我们必须在使用array[i][j]
语法之前转换为指向二维数组类型的指针。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
size_t rows;
size_t cols;
double data[];
} Matrix;
Matrix* make_matrix (size_t n_rows, size_t n_cols) {
Matrix* mat = malloc(sizeof(Matrix) + sizeof(double[n_rows][n_cols]));
if(mat == NULL)
{
return NULL;
}
mat->rows = n_rows;
mat->cols = n_cols;
return mat;
}
Matrix* copy_matrix (const double* data, size_t n_rows, size_t n_cols) {
Matrix* mat = make_matrix(n_rows, n_cols);
double (*new_data)[mat->cols];
new_data = (double(*)[mat->cols]) mat->data;
for(size_t i = 0; i < mat->rows; i++)
{
for(size_t j = 0; j < mat->cols; j++)
{
new_data[i][j] = data[i] + j;
}
}
return mat;
}
void print_matrix (const Matrix* mat)
{
double (*data)[mat->cols];
data = (double(*)[mat->cols]) mat->data;
for(size_t i = 0; i < mat->rows; i++)
{
for(size_t j = 0; j < mat->cols; j++)
{
printf("%g ", data[i][j]);
}
printf("\n");
}
}
int main (void) {
double a[] = {
1, 2, 3,
4, 5, 6,
7, 8, 9 };
Matrix* m1 = copy_matrix(a, 3, 3);
print_matrix(m1);
puts("");
double a2[] = {
1, 2, 3,
4, 5, 6 };
Matrix* m2 = copy_matrix(a2, 2, 3);
print_matrix(m2);
puts("");
double a3[] = {
1, 2,
3, 4,
5, 6 };
Matrix* m3 = copy_matrix(a3, 3, 2);
print_matrix(m3);
free(m1);
free(m2);
free(m3);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.