C - 使用结构指针作为参数在函数内分配结构
C - Allocate a struct within a function using the struct pointer as argument
我正在使用 Ruby C API。我需要从一个函数中创建一个结构,但我认为我犯了一些分配错误。这是我的代码
#include <stdio.h>
#include <ruby.h>
#include <ruby/thread.h>
typedef struct {
double *matrix;
int nrows;
int ncols;
}Matrix;
void createMatrix(VALUE matrix, Matrix *mat) {
printf("In\n");
mat->nrows = RARRAY_LEN(matrix);
VALUE firstElement = rb_ary_entry(matrix, 0);
mat->ncols = RARRAY_LEN(firstElement);
printf("Matrix shape: (%d,%d)\n", mat->nrows, mat->ncols);
int i,j;
double *tempMat = (double *)malloc(mat->nrows * mat->ncols * sizeof(double));
printf("Allocated\n");
VALUE row;
for (i=0; i<mat->nrows; i++)
{
row = rb_ary_entry(matrix, i);
for (j=0; j<mat->ncols; j++)
{
tempMat[i * mat->ncols + j] = NUM2DBL(rb_ary_entry(row, j));
// printf("Matrix A Element(%d,%d)=%f\n", i, j, matA[i * colsA + j]);
}
}
mat->matrix = tempMat;
for (i=0; i<mat->nrows; i++)
{
for (j=0; j<mat->ncols; j++)
{
printf("Matrix temp Element(%d,%d)=%f\n", i, j, mat->matrix[i * mat->ncols + j]);
}
}
printf("Assigned\n");
return;
}
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int i,j;
Matrix *matA;
createMatrix(matrixA, matA);
Matrix *matB;
createMatrix(matrixB, matB);
return Qnil;
}
void Init_la_ruby_ext()
{
VALUE rg = rb_define_module("RG");
VALUE linalg = rb_define_module_under(rg, "LinearAlgebra");
VALUE operation = rb_define_class_under(linalg, "Operation", rb_cObject);
rb_define_method(operation, "matmat_mul", matmat_mul, 2);
}
extconf.rb
文件是
require 'mkmf'
extension_name = 'la_ruby_ext'
create_makefile(extension_name)
你可以 运行 通过
进行测试
require './la_ruby_ext'
rows = 3
cols = 3
mat = Array.new(rows){Array.new(cols)}
mat[0] = [0.0, 1.0, 2.0]
mat[1] = [3.0, 4.0, 5.0]
mat[2] = [6.0, 7.0, 8.0]
operation = RG::LinearAlgebra::Operation.new
matC = operation.matmat_mul(mat, mat.transpose)
正如您从 运行 测试中看到的那样,代码在我第二次调用函数 createMatrix
时给出了分段错误。这是我的理解:
- 我首先创建一个指向
struct Matrix
的指针
- 然后我将这个指针作为参数传递给
createMatrix
- 我分配一个指向二维数组的指针
- 创建二维数组
- 我把指针赋给matrix->nmatrix
有什么想法吗?这是正确的做法吗?
鉴于定义 void createMatrix(VALUE xxx, Matrix *mat)
和函数内部 mat->nrows = …
等的使用,matmul_mul()
中对 createMatrix()
的调用是错误的。
您有:
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int i,j;
Matrix *matA;
createMatrix(matrixA, matA);
Matrix *matB;
createMatrix(matrixB, matB);
你需要:
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int i,j;
Matrix matA;
createMatrix(matrixA, &matA);
Matrix matB;
createMatrix(matrixB, &matB);
在当前代码中,您将未初始化的指针传递给 createMatrix()
,然后分配给指针指向的 'random' 内存。这很少会带来幸福。在修改后的代码中,您有一对 Matrix
值,您将指向这些值的指针传递给 createMatrix()
函数,然后函数会为您填写详细信息。
我正在使用 Ruby C API。我需要从一个函数中创建一个结构,但我认为我犯了一些分配错误。这是我的代码
#include <stdio.h>
#include <ruby.h>
#include <ruby/thread.h>
typedef struct {
double *matrix;
int nrows;
int ncols;
}Matrix;
void createMatrix(VALUE matrix, Matrix *mat) {
printf("In\n");
mat->nrows = RARRAY_LEN(matrix);
VALUE firstElement = rb_ary_entry(matrix, 0);
mat->ncols = RARRAY_LEN(firstElement);
printf("Matrix shape: (%d,%d)\n", mat->nrows, mat->ncols);
int i,j;
double *tempMat = (double *)malloc(mat->nrows * mat->ncols * sizeof(double));
printf("Allocated\n");
VALUE row;
for (i=0; i<mat->nrows; i++)
{
row = rb_ary_entry(matrix, i);
for (j=0; j<mat->ncols; j++)
{
tempMat[i * mat->ncols + j] = NUM2DBL(rb_ary_entry(row, j));
// printf("Matrix A Element(%d,%d)=%f\n", i, j, matA[i * colsA + j]);
}
}
mat->matrix = tempMat;
for (i=0; i<mat->nrows; i++)
{
for (j=0; j<mat->ncols; j++)
{
printf("Matrix temp Element(%d,%d)=%f\n", i, j, mat->matrix[i * mat->ncols + j]);
}
}
printf("Assigned\n");
return;
}
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int i,j;
Matrix *matA;
createMatrix(matrixA, matA);
Matrix *matB;
createMatrix(matrixB, matB);
return Qnil;
}
void Init_la_ruby_ext()
{
VALUE rg = rb_define_module("RG");
VALUE linalg = rb_define_module_under(rg, "LinearAlgebra");
VALUE operation = rb_define_class_under(linalg, "Operation", rb_cObject);
rb_define_method(operation, "matmat_mul", matmat_mul, 2);
}
extconf.rb
文件是
require 'mkmf'
extension_name = 'la_ruby_ext'
create_makefile(extension_name)
你可以 运行 通过
进行测试require './la_ruby_ext'
rows = 3
cols = 3
mat = Array.new(rows){Array.new(cols)}
mat[0] = [0.0, 1.0, 2.0]
mat[1] = [3.0, 4.0, 5.0]
mat[2] = [6.0, 7.0, 8.0]
operation = RG::LinearAlgebra::Operation.new
matC = operation.matmat_mul(mat, mat.transpose)
正如您从 运行 测试中看到的那样,代码在我第二次调用函数 createMatrix
时给出了分段错误。这是我的理解:
- 我首先创建一个指向
struct Matrix
的指针
- 然后我将这个指针作为参数传递给
createMatrix
- 我分配一个指向二维数组的指针
- 创建二维数组
- 我把指针赋给matrix->nmatrix
有什么想法吗?这是正确的做法吗?
鉴于定义 void createMatrix(VALUE xxx, Matrix *mat)
和函数内部 mat->nrows = …
等的使用,matmul_mul()
中对 createMatrix()
的调用是错误的。
您有:
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int i,j;
Matrix *matA;
createMatrix(matrixA, matA);
Matrix *matB;
createMatrix(matrixB, matB);
你需要:
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
{
int i,j;
Matrix matA;
createMatrix(matrixA, &matA);
Matrix matB;
createMatrix(matrixB, &matB);
在当前代码中,您将未初始化的指针传递给 createMatrix()
,然后分配给指针指向的 'random' 内存。这很少会带来幸福。在修改后的代码中,您有一对 Matrix
值,您将指向这些值的指针传递给 createMatrix()
函数,然后函数会为您填写详细信息。