在C中使用释放和重用指针来转置数组

时间:2017-05-05 18:57:23

标签: c arrays

我一直致力于显示转换包含整数的2D数组的结果的代码。我的目标是用它的转置替换原始数组而不是创建副本,并且在内存分配方面我遇到了一个问题。在开始我通过scanf()得到行数(m)和列(n),然后在main()函数中为数组分配内存,如下所示:

int **mtr=(int **)malloc(m*sizeof(int *));
for(int i=0;i<m;i++)
    mtr[i]=(int *)malloc(n*sizeof(int));

然后我调用我的函数来转置看起来如下的数组:

void transposeMatrix(int m,int n,int mtr[m][n])
{
    int temp[m][n];
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            temp[i][j]=mtr[i][j];
        }
    }
    for(int i=0;i<m;i++)
        free(mtr[i]);
    free(mtr);
    mtr=(int **)malloc(n*sizeof(int *));
    for(int i=0;i<n;i++)
        mtr[i]=(int *)malloc(m*sizeof(int));
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            mtr[i][j]=temp[j][i];
        }
    }
}

我的目标是首先将原始'mtr'的值存储在临时'temp'数组中,然后释放分配给'mtr'的内存,然后再次分配内存以使用列切换行以便使用相同的'mtr'回到主()。但是在行:

mtr[i]=(int *)malloc(m*sizeof(int));

我得到“错误:赋值给带数组类型的表达式”。那个时候不应该释放mtr [i]吗?有谁知道问题出在哪里?

1 个答案:

答案 0 :(得分:2)

此:

int **mtr /* ... */;

声明指向int的指针。目标指针可能是此类指针数组中的第一个,但在任何情况下都不涉及此处涉及的2D数组。 2D数组是一个数组数组,其内存中的所有成员数组都是连续的。使用指向数组的指针数组不能保证这一点(只有指针必须是连续的,而不是它们所指向的对象)。而且,mtr指针不能直接转换为指向第一个元素指向的数组的第一个int的指针。

您可以使用指针数组表单的方式,使用许多与 bona fide 2D数组相同的方法,但作为此函数的参数不是其中之一:

void transposeMatrix(int m,int n,int mtr[m][n])

你的编译器应该发出警告。最简单的解决方案,至少让你超越第一个障碍,就是将函数声明为接受正确类型的参数:

void transposeMatrix(int m,int n,int **mtr) { // ...
但是,你仍然会遇到麻烦,因为虽然该函数可以重新分配或释放+ malloc其mtr参数指向的内存,但不会修改调用者的内容。那个指针的副本。有两种方法可以解决这个问题:

  1. 声明函数接受指向调用者指针的指针,或
  2. 让函数返回修改后的指针值。
  3. 实现后者需要对代码进行更少的更改:

    int **transposeMatrix(int m,int n,int **mtr) {
        // ...
        return mtr;
    }
    
    // ...
    
    // call the function as:
    mtr = transposeMatrix(m, n, mtr);