将Matrix表示为结构并填充随机值

时间:2012-12-31 17:23:30

标签: c function data-structures

我已经定义了一个新的 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;
}

我认为有两个问题: 1:由于某种原因,如上所述在main()中设置“rows”和“columns”的值是错误的。 2:我的gen_matrix函数也可能存在一些问题。

所以我的问题是,我如何纠正这两个问题? (注意:我的random()函数绝对可以。)

2 个答案:

答案 0 :(得分:1)

你有一些错误,其中一个是你以错误的方式分配空间,newdata的类型是MATRIX而不是double,将其更改为:

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

不要施放malloc;)

答案 1 :(得分: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,以免long int random()中声明的stdlib.h产生歧义(gcc版本4.6 0.3)。

  5. 另一个建议是打开编译器的警告,这样你就可以预先检测到一些问题

    更新:应用了上述所有更正的程序。 (它使用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;
    }