如何使用动态内存分配处理C中的矩阵



我试图运行一个模拟,其中我需要填充三个大小为"2x迭代"的矩阵,这是(迭代=)10^8列和2行。我还使用大小为10^8的向量t。使用动态内存分配,我编写了以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define T 10000
#define dt 0.0001
#define iterations (T/dt)
/*(more code)*/
int main(){
  int i, j;
  double *t;
  double (*x)[2], (*y)[2], (*c)[2];
  t=(double *) malloc((iterations-1)*sizeof(double));
  x=(double (*)[2]) malloc((2*(iterations))*sizeof(double));
  y=(double (*)[2]) malloc((2*(iterations))*sizeof(double));
  c=(double (*)[2]) malloc((2*(iterations))*sizeof(double));
  for(i=0; i=1; i++){
   x[i][0]=50+500*i;
   y[i][0]=300;
   c[i][0]=15;
  }
  for(j=0; j<=iterations-2; j++){
   t[j+1]=t[j]+dt;
   /*(more code)*/
   printf("%G %G %G %G %G %Gn",x[0][j+1],x[1][j+1],y[0][j+1],y[1][j+1],c[0][j+1],c[1][j+1]);
  }
  return 0;
}

动态内存分配是否正确写入?我的意思是,我真的有一个大小为"迭代"的向量t和大小为"2x迭代"的三个矩阵吗?

如果我想填充矩阵的每个分量,例如,我想在矩阵x的位置(1,4)上加一个50,那么我必须写x[1][4]=50吗?(就像第一个"for"一样。)

问题是,在执行程序时,我遇到了一个错误:分段错误。然后,使用调试器,我得到以下内容:

程序接收到信号SIGSEGV,分段故障。

x[0][0]=50

分配矩阵的通用方法:

double **mat_init(int n_rows, int n_cols)
{
    double **m;
    int i;
    m = (double**)malloc(n_rows * sizeof(double*));
    for (i = 0; i < n_rows; ++i)
        m[i] = (double*)calloc(n_cols, sizeof(double));
    return m;
}    
void mat_destroy(int n_rows, double **m)
{
    int i;
    for (i = 0; i < n_rows; ++i) free(m[i]);
    free(m);
}

你也可以这样做:

double **mat_init2(int n_rows, int n_cols)
{
    double **m;
    int i;
    m = (double**)malloc(n_rows * sizeof(double*));
    m[0] = (double*)calloc(n_rows * n_cols, sizeof(double));
    for (i = 1; i < n_rows; ++i)
        m[i] = m[i-1] + n_cols;
    return m;
}    
void mat_destroy2(double **m)
{
    free(m[0]); free(m);
}

对于以上两种方法,都可以使用matrix[row][col]访问单元格。有时,您可能更喜欢分配单个数组,并使用matrix[row*n_cols+col]访问单元。

顺便说一句,我相信有人会说"不要使用演员阵容",但使用演员阵容也有好处——这不是话题。

我的意思是,我真的有一个向量t大小的"迭代"吗

t=(double *) malloc((iterations-1)*sizeof(double));
                            ^^^

既然你减去一,答案是否定的。

以及大小为"2x迭代"的三个矩阵?

是的,你有三个大小为"2x迭代"的矩阵。然而,你所拥有的相当于:

double m[iterations][2];

所以您有"迭代"行和2列。

请记住始终检查"内存不足",即

p = malloc(....);
if (p == NULL)
{
    printf("out of memn");
    return -1;
}

所以你访问它就像:

m[0][0]
m[0][1]
m[1][0]
m[1][1]
m[2][0]
m[2][1]
m[3][0]
......

最新更新