【问题标题】:On Dynamic Allocation of Matrices论矩阵的动态分配
【发布时间】:2014-03-25 03:07:50
【问题描述】:

通常人们将矩阵动态分配为

double **A;

int N,i,j;

N=10;

A = (double **)malloc(N*sizeof(double *));

   for(i=0; i<N; i++)
    {
    A[i]= (double *)malloc(N*sizeof(double ));
    }

根据课堂上的一些讨论,我了解到这对于大型矩阵不是很有效。这会创建一个指向分配在内存中不同位置的数组的指针数组,在这种分配中更改行的成本更高。所以导师建议使用这种分配方式:

double *A;

int N;

N=10;

A = (double *)malloc(N*N*sizeof(double));

通过查看 A[N*i + j] 来访问矩阵的 i,j 元素。我想像这样分配我的矩阵,但我想保留我的旧符号 A[i][j]。因此,我想到的一种方法是首先进行错误分配,即创建 double** A,如第一部分所述。然后设置

 A = (double **)malloc(N*sizeof(double *));
 temp = (double *)malloc(N*N*sizeof(double ));

 for(i=0; i<N; i++)
    {   
        A[i]=&temp1[i*N+j];    
    }

这段代码似乎可以工作,但我只知道内存分配的基础知识,所以我想问一下这种分配是否有任何问题,与仅仅保持数组 temp1 有什么不同。谢谢

【问题讨论】:

  • @Quest 这不是重复的。
  • 是的,这个线程不是关于每个元素的地址分配到哪里。但是尽管我意识到我的代码中有一个愚蠢的错误,但我不知道它是如何运行的,但这不是真的。
  • 问题是j没有初始化所以你设置随机地址...但是如果j是0或者你在初始化中省略了j这个词,那么你应该没问题.一些编译器在指向数组的指针方面存在问题——这可能是您的 Tiny C 编译器不能很好地处理建议的解决方案的原因。

标签: c arrays matrix


【解决方案1】:

这很容易做到,只需将A 声明为指向行数组的指针:

double (*A)[N] = malloc(N*sizeof(*A));

for(int i = 0; i < N; i++) {
    for(int j = 0; j < N; j++) {
        A[i][j] = /*whatever*/;
    }
}

如果您不清楚我使用的符号,请从内到外阅读:A 被定义为指向 N 元素数组 ((*A)[N]) 的指针 ((*A)),发生这种情况类型为double (double (*A)[N])。该指针使用返回值malloc() 进行初始化(= 不遵循标识符A 可能令人恼火,但这与char myName[] = "Foo, Bar B."; 中的语法相同)。如果您拆分线路和/或使用typedef,可能会更清楚一点:

double (*A)[N];
A = malloc(N*sizeof(*A));

typedef double MatrixLine[N];
MatrixLine* A = malloc(N*sizeof(*A));

在 C(不是 C++)中,typedef 工作正常,即使 N 是一个动态计算的值,我什至可以使用 typedef double MatrixLine[random()];,但这并没有多大意义...... C 在尊重!

了解如何将指针转换为 A 的类型可能也很有趣,以下是正确的转换:

double (*A)[N];
A = (double (*)[N])malloc(N*sizeof(*A));

请注意,转换的语法与 A 的声明完全相同,只是省略了标识符。


注 1:
从 C99 开始,您可以在 for() 语句中声明循环变量。使用它,它会使您的代码更具可读性。

注2:
在 C 中,不需要强制转换 malloc() 的返回值,并且无论如何它都不会添加到您的代码中来编写它。但是,C++ 确实需要强制转换,因此如果您想在 C++ 项目中使用您的代码,请继续进行强制转换。

【讨论】:

  • 这里的分配是N不是动态的吧?当我尝试运行它时,它会给出预期的错误常量表达式,我猜这意味着 N?还有符号 double (A)[N] = malloc(Nsizeof(A));对我来说有点困惑。它创建什么样的对象?是 double* 还是别的什么?谢谢
  • 你没有使用 C++ 编译器来编译这段 C 代码,是吗?因为 C++ 在数组大小方面比 C 更严格。在 C 中,将 N 设置为动态计算值是完全可以的;然而,C++ 要求所有数组大小都是常量。至于符号,我将尝试在我的答案中添加一些解释。稍等片刻。
  • 我正在使用 tinyc c 编译器
  • 我从未使用过 tinyc(直到几分钟前我才知道它的存在),所以我不知道它在实现各种语言标准方面的效果如何。至少从 C99 开始,可变长度数组就是该语言的一部分,因此,我给出的代码可以使用 gcc -std=c99 编译得很好。所以在我看来,好像 tinyc 没有完全/正确地实现语言标准。
  • 我不知道为什么,但我只是运行int N; N=100; double (*A)[N]; A = malloc(N*sizeof(*A)); 来看看它是如何工作的,但它说预期是常量表达式。我会尝试 gcc 并返回谢谢。
猜你喜欢
  • 1970-01-01
  • 2021-10-13
  • 2023-03-03
  • 2021-12-19
  • 2010-11-27
  • 2015-10-14
  • 2015-11-10
  • 1970-01-01
  • 2011-07-07
相关资源
最近更新 更多