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 用随机双精度值填充这个结构。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() 中设置“行”和“列”的值是错误的。2:我的 gen_matrix 函数也可能有问题。

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

4

2 回答 2

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

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

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