指向2darrays和手动内存管理的指针 – C.

我认为在纯C中构建一个处理各种矩阵计算的库是一个很好的挑战。现在,尽管我对Objective-C和Cocoa有一些非常好的经验,但我对C的知识才是我需要的。使用Objective-C而不是更多。 所以,例如,我熟悉C中指针,数组等的概念,但不熟悉malloc和free(ARC是幸福!)。 我决定接受这个项目,这样我就可以获得更多的C体验(当然,除了有很多乐趣之外!)。

到目前为止,我有一个像这样定义的矩阵:

typedef float mReal; typedef struct { mReal **v; int w; int h; } matrix; 

当然,我还需要一种方法来为我提供一个我想要的全新矩阵:

 void new_matrix(matrix *m, int w, int h) { m = malloc(sizeof(matrix)); m->w = w; m->h = h; m->v = malloc(w * sizeof *(m->v)); for (int i = 0; i v[i] = malloc(h * sizeof *(m->v[i])); } } 

在我的main()函数中,我决定给我的新方法一个旋转:

 int main() { matrix m; new_matrix(&m, 5, 5); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { mv[i][j] = i*j; } } for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { printf("%f", mv[i][j]); } } } 

现在,您可能已经从查看代码中猜到了它,但是当我尝试将某些内容写入矩阵时,这会崩溃,更具体地说,在此行上:

 mv[i][j] = i*j; 

在我理解问题的失败尝试中,我将前两个嵌套for循环从main()new_matrix() ,并在malloc’ing之后直接写入。 这很有效。 所以我想问题一定是因为矩阵在一个函数中被malloc化而在另一个函数中被改变了?

你的问题在这里:

 new_matrix(&m, 

您已经为堆栈上的矩阵分配了空间,并将其地址传递给new_matrix

然后new_matrix分配一个新的:

 m = malloc(sizeof(matrix)); 

这种新结构永远不会逃脱new_matrix

要么new_matrix返回指向矩阵的指针,

 matrix * new_matrix(int w, int h) { ... } 

或者让new_matrix对传入的m进行操作。

我认为这条线需要

 m->v = malloc(w * sizeof *(m->v)) 

需要是

 m->v = malloc(w * sizeof *(mReal)) 

因为数组v是mReal指针的数组

然后

 m->v[i] = malloc(h * sizeof *(m->v[i])) 

应该

 m->v[i] = malloc(h * sizeof (mReal)) 

保持实际的mReal值

 m->v = malloc(w * sizeof *(m->v)); for (int i = 0; i < w; i++) { m->v[i] = malloc(h * sizeof *(m->v[i])); } 

以上几行是这样做的:

  1. 将sizeof(指向m-> v的指针)的w计数分配给m-> v。 指针是按值整数,所以假设你使用32位整数,你在m-> v分配4w字节
  2. 对于每个m-> v位置,分配sizeof of countof(指向m-> v [i]的指针)。 这是分配的另一个4h字节,故意为m-> v [i]。

现在,我不确定m-> v [i]现在指向哪里……所以对随机mv [i] [j]的调用很可能会导致seg错误。

我理解你想要v指向aw * h 2D数组的内存空间,所以你应该这样做

 &v = (mReal *) malloc(w * h * sizeof(mReal)); 

而不是我引用的块。 您将能够以2Darrays的forms遍历内存块。 我刚刚做了实验。 2D数组实际上是连续的内存块。 C编译器将在后面处理地址计算。 所以做上述事情应该可以解决您的问题。

是的, m = malloc(sizeof(matrix)); 是多余的。 该行将声明矩阵结构的存储空间并将其分配给m。 当你的m通过引用传入时,你的初始matrix m; 从主线已经这样做了。

@woolstar,构造函数样式函数如matrix * new_matrix(int w, int h) {...}在使用纯C时不是一个好主意。尝试在旧的Diab C编译器上运行…