0

私は次のように新しいtypedefを定義しました:

typedef struct matrep
{
       int rows, columns; /*rows/columns represent the number of rows/columns in the matrix, data represents matrix entries.*/
       double *data;
} 
       MATRIX;

今、私がやろうとしているのは、関数gen_matrixを使用して、この構造体をランダムなdouble値で埋めることです。gen_matrixは、MATRIX構造へのポインターを受け取り、同じものを返します。

ただし、以下のプログラムを実行すると、ランタイムエラーが発生します。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct matrep
{
       int rows, columns; //rows and columns represent the number of columns in the matrix, data represents matrix entries.//
       double *data;
} 
       MATRIX; 

double random();
MATRIX *gen_matrix(MATRIX *ptr);

int main()
{
  MATRIX *somepointer;

  somepointer -> rows = 2;  //The program crashes when I try to execute this.//
  somepointer -> columns = 2;

}

double random()
{
       double f = (double)rand() / RAND_MAX; //Generating a random number between -100 and 100//
       return (-100 + f*(200));         
}

MATRIX *gen_matrix(MATRIX *ptr)
{
       int i, j;
       int m, n;     
       MATRIX *newdata;

       m = ptr -> rows;
       n = ptr -> columns;

       newdata = (MATRIX *)malloc(sizeof(double)*(m*n)); //Allocating suitable space.//
       ptr = newdata;

       for(i = 0; i < m; i++)
       {
             for(j = 0; j < n; j++)
             {
                *(ptr -> data)= random(); //Setting the value of each and every matrix entry to a random double.//
                 (ptr -> data)++; 
             }

       }

       return ptr;
}

2つの問題があると思います:1:何らかの理由で、上記のようにmain()で「行」と「列」の値を設定するのは間違っています。2:gen_matrix関数にも問題がある可能性があります。

だから私の質問は、どうすれば両方の問題を修正できるでしょうか?(注:私のrandom()関数は間違いなく大丈夫です)。

4

2 に答える 2

1

いくつかのエラーがあります。そのうちの1つは、スペースを間違った方法で割り当てていることです。newdataのタイプはMATRIXであり、doubleではありません。これを次のように変更してください。

newdata = malloc(sizeof(*newdata));
newdata->data = malloc(sizeof(double)*(m*n));

そして、mallocをキャストしないでください;)

于 2012-12-31T17:32:30.200 に答える
0

コードにはいくつかの問題があります。そのうちのいくつかを次に示します。

  1. somepointer初期化せずにポインタ変数にアクセスしています。これが最初のクラッシュの原因です。mainルーチンを次のように変更してください。

    int main() {
        MATRIX *somepointer = (MATRIX*) malloc(sizeof(MATRIX));
        somepointer -> rows = 2;  
        somepointer -> columns = 2;
    
        MATRIX *another_matrix = gen_matrix(somepointer);
    
        // Don't forget to free your stuff
        free(somepointer);
        free(another_matrix);
    }
    
  2. gen_matrix将来のクラッシュを回避するために、関数のメモリ割り当てを変更してください。

    // Here do another malloc to avoid another access without initialization crash
    MATRIX *newdata = (MATRIX*) malloc(sizeof(MATRIX));
    
    m = ptr -> rows;
    n = ptr -> columns;
    
    newdata->data = (double*) malloc(sizeof(double) * (m * n)); 
    ptr = newdata;
    
  3. 配列初期化ループはdataポインターをインクリメントしますが、ループの最後でポインターがデータの最後の要素を指すため、正しくありません。ポインタ演算を使用して配列要素にアクセスし、配列[col、row]の位置に基づいてメモリインデックスを計算できます。

    for(i = 0; i < m; i++)
       for(j = 0; j < n; j++) {
          // Memory address for array position i, j formula:
          // array-base-position + (total-colums * current-row) + current-col
          // example: given total-colums = 5, current-row = 1 and current-col = 3
          // you'll get:  ptr + (5 * 1) + 4 = 8
          // 
          //  ptr
          //  v
          //  ---------------------
          //  | 0 | 1 | 2 | 3 | 4 |
          //  ---------------------
          //  | 5 | 6 | 7 | 8 | 9 |
          //  ---------------------
          //  ...           ^ here 
    
          *(ptr -> data + (n * i) + j) = random();
       }
    }
    
  4. 提案として、random関数の名前を次のような名前に変更して、で宣言drandomされたものとあいまいさが生じないようにします(gccバージョン4.6.3)。long int random()stdlib.h

もう1つの提案は、コンパイラの警告をオンにして、この問題のいくつかを事前に検出できるようにすることです。

更新:上記のすべての修正が適用されたプログラム。(gccバージョン4.6.3を使用すると、クラッシュすることなく実行されます。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct matrep {
    int rows, columns;
    double *data;
} MATRIX;

double drandom();
MATRIX *gen_matrix(MATRIX *ptr);

int main() {
    MATRIX *somepointer  = (MATRIX*) malloc(sizeof(MATRIX));
    somepointer->rows = 2;
    somepointer->columns = 2;

    MATRIX *another_matrix = gen_matrix(somepointer);

    free(somepointer);
    free(another_matrix->data);
    free(another_matrix);
}

double drandom() {
    double f = (double) rand() / RAND_MAX;
    return (-100 + f*(200));
}

MATRIX *gen_matrix(MATRIX *ptr) {
    MATRIX *newdata = (MATRIX*) malloc(sizeof(MATRIX));
    int nrows = ptr->rows;
    int ncols = ptr->columns;

    newdata->data = (double*) malloc(sizeof(double) * (nrows * ncols));
    for(int row = 0; row < nrows; row++) {
        for(int col = 0; col < ncols; col++) {
            *(newdata->data + (ncols * row) + col) = drandom();
        }
    }
    return newdata;
}
于 2012-12-31T18:05:55.153 に答える