【问题标题】:double pointer and memory allocation双指针和内存分配
【发布时间】:2013-12-06 21:55:32
【问题描述】:

我有一个使用双指针创建矩阵的结构:

typedef struct
{
       int rows, cols;
       int** element;
}Matrix;

我正在编写一个函数,该函数通过动态分配内存给这个结构来初始化一个矩阵。这是我编写的代码,但是当我尝试访问另一个函数或 main 中的 a->rows、cols 或元素时出现分段错误。

void matrixInit (Matrix* ma, int m, int n)
 {   int i;
     ma=(Matrix*)malloc(sizeof(Matrix));
     ma->rows=m;
     ma->cols=n;

     ma->element=malloc(m*sizeof(int*));
     for(i=0;i<m;i++)
        {ma->element[i]=malloc(n*sizeof(int));
        }

 }

有什么帮助吗?

【问题讨论】:

  • ma的声明在哪里?为什么你有两个名为 m 的参数?
  • 是的。对不起。它最初被命名为 matx,我将其改为 m 以使其更简单。
  • 您应该展示一个导致分段错误的访问示例。
  • 现在应该是正确的
  • 您需要传入一个指向矩阵的指针,以便调用者可以使用malloced 指针。还要检查malloc 是否不返回NULL,也不要强制转换第一个malloc(分配ma 的那个)。

标签: c pointers matrix struct


【解决方案1】:

在 C 中,每个函数参数都是按值传递的。这意味着当您为函数提供参数时,值的副本(而不是值本身)将作为函数中的参数传递。这包括指针 - 您可以更改指针所指的任何内容并且没有问题,但如果您将指针设置为指向函数中的其他内容,则更改仅适用于指针的本地副本。

ma=(Matrix*)malloc(sizeof(Matrix));

这里,不是让输入指针指向为Matrix 结构新分配的内存,而是实际上用新指针覆盖本地指针ma,而不对输入指针做任何事情。这会导致问题。要解决此问题,您可以改为返回指向 ma 的指针。

【讨论】:

  • 谢谢!我现在明白为什么它会出现故障。但是有没有什么方法可以在不改变函数参数的情况下访问函数中创建的矩阵呢?
  • 如果你让它返回一个指向新分配的Matrix的指针,你不需要改变参数(虽然第一个参数,本质上是一个输出参数,如果你也退货)。或者,您可以将Matrix** 作为第一个参数传递并更改它在函数内部引用的Matrix*
【解决方案2】:

当你调用这样的函数时,你将一个指向矩阵的指针的值传递给它。当你实际在函数中创建矩阵时,你只是在本地分配它。

您应该将指针传递给要存储矩阵指针的变量,即Matrix **ma

void matrixInit (Matrix **ma_ptr, int m, int n)
{
    int i;
    *ma_ptr = (Matrix*)malloc(sizeof(Matrix));

    Matrix *ma = *ma_ptr;
    ma->rows=m;
    ma->cols=n;
    ma->element=malloc(m*sizeof(int*));
    for(i=0;i<m;i++)
    {
        ma->element[i]=malloc(n*sizeof(int));
    }
}

然后使用您希望存储矩阵的变量的地址调用此方法。

Matrix *m;
matrixInit(&m, 4, 4);

另一种方法是为矩阵本身在函数之外分配内存。 您的函数将完全保持您编写它的方式,除非您删除分配

ma = (Matrix*)malloc(sizeof(Matrix));

然后你将传递一个指向 Matrix 的指针,但你必须确保它指向一个 Matrix 结构。您可以通过声明 Matrix* 变量并在函数外部调用 malloc() (从而将其分配到堆上)来实现此目的,或者声明 Matrix 类型的变量(并将其分配到堆栈上)。

Matrix ma;
matrixInit(&ma, 4, 4);

【讨论】:

  • 您的代码运行良好,但我这样做是为了分配,我们被特别告知要有一个函数,其输入是矩阵指针,而不是双指针。
  • 您可以通过从函数中删除分配、声明Matrix m 并改为使用&amp;m 调用函数来实现此目的。
【解决方案3】:

您需要传入一个指向矩阵的指针,以便调用者可以使用分配的指针。像这样:

void matrixInit (Matrix ** ma, int m, int n)
{
    *ma = malloc(sizeof **ma); // sizeof **ma == sizeof(Matrix)

然后用这个来调用它:

Matrix * matx;
matrixInit(&matx, 3, 4);

【讨论】:

    【解决方案4】:

    您的函数不会返回它创建的矩阵。改为这样做。

    Matrix * matrixInit (int m, int n)
     {
       Matrix* ma;
       int i;
         ma=(Matrix*)malloc(sizeof(Matrix));
         ...
         return ma;
     }
    

    ...然后这样使用它

    Matrix * myMatrix;
    myMatrix = matrixInit(8,8);  // chessboard
    

    【讨论】:

      猜你喜欢
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2021-03-18
      • 2021-12-11
      • 2015-02-27
      • 1970-01-01
      相关资源
      最近更新 更多