2016-05-11 13 views
1

Ruby C APIを使用しています。私は関数内から構造体を作成する必要がありますが、私はいくつかの割り当てエラーを起こしていると思います。この私のコードC - structポインタを引数として使用して関数内に構造体を割り当てよう

#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) 

でテストを実行することができます2回目の私は関数createMatrixを呼び出します。これが私の理解です:私は、私は2次元配列を作成して2次元配列

  • へのポインタを割り当てるcreateMatrix
  • に引数としてこのポインタを渡し、私が最初にstruct Matrix
  • へのポインタを作成

    1. 私はmatrix-> nmatrixにポインタを割り当てます

    何か考えてください。これはこれを行う正しい方法ですか?

  • 答えて

    1

    定義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()に初期化されていないポインタを渡した後、ポインタが指し示すことを「ランダム」メモリに割り当てます。これはめったに幸福につながりません。改訂されたコードでは、Matrixの値が1組あり、そのポインタをcreateMatrix()関数に渡して、詳細を入力します。

    関連する問題