动态内存分配问题(C)



考虑以下代码:

#include <stdio.h>
#include <malloc.h>
void allocateMatrix(int **m, int l, int c)
{
    int i;
    m = (int**) malloc( sizeof(int*) * l );
    for(i = 0; i < l; i++)
        m[i] = (int*) malloc( sizeof(int) * c );
}
int main()
{
    int **m;
    int l = 10, c = 10;
    allocateMatrix(m, l, c);
    m[0][0] = 9;
    printf("%d", m[0][0]);
    return 0;
}

上面的代码将生成内存分配错误并崩溃。

但下面的代码将正确工作,问题是:为什么?

#include <stdio.h>
#include <malloc.h>
int** allocateMatrix(int l, int c)
{
    int i;
    int **m = (int**) malloc( sizeof(int*) * l );
    for(i = 0; i < l; i++)
        m[i] = (int*) malloc( sizeof(int) * c );
    return m;
}
int main()
{
    int **m;
    int l = 10, c = 10;
    m = allocateMatrix(l, c);
    m[0][0] = 9;
    printf("%d", m[0][0]);
    return 0;
}

我不明白为什么第一个代码会崩溃,因为我只是将指针传递给指针m(保存矩阵内存第一个内存地址的变量)作为参数。(在实践中)我看不出代码之间有什么区别。如果有任何明确的解释,我将不胜感激。

谢谢,Rafael Andreatta

在第一个例子中,您没有初始化m。您只更改了它的副本。因此,否则,调用者将永远看不到您对m做了什么。

在第二个例子中,您分配内存,然后返回一个指向它的指针。这是有效的。

你也许可以像这样修复你的第一个例子(未经测试但应该有效):

void allocateMatrix(int ***m, int l, int c)
{
    int i;
    *m = malloc( sizeof(int*) * l );
    for(i = 0; i < l; i++)
        (*m)[i] = malloc( sizeof(int) * c );
}

/* ... */
allocateMatrix(&m, l, c);

编辑

我花了一段时间,但我找到了。和往常一样,C常见问题解答对此有话要说。

函数allocateMatrix接收传递的变量m的副本,而不是您从main传递的变量The。因此,在第一个示例中,m没有初始化,当您尝试访问is时,会出现分段错误。

这是一个棘手的问题,发生这种情况是因为:

void allocateMatrix(int **m, int l, int c);

你是一个间接的层次。如果传递指针,则指向的值实际上是通过引用传递的。但是,实际的指针值被复制到堆栈上,即仍然是按值传递的。因此,您的分配函数有一个堆地址的本地副本,但它从未在前面的作用域中重新分配给m

要解决这个问题,你可以使用第二种情况,或者这个:

void allocateMatrix(int ***m, int l, int c)
{
    int i;
    *m = (int**) malloc( sizeof(int*) * l );
    for(i = 0; i < l; i++)
        (*m)[i] = (int*) malloc( sizeof(int) * c );
}

并与CCD_ 3一起通过。

我还想指出,在C中,您可能最好不要强制转换malloc的结果,尽管在C++中需要这样做。看看这个答案。

因为在第一个例子中变量m(在main中)没有改变。若要更改它,必须将它作为引用(在C++中)或通过指针(在纯C中)传递。

相关内容

  • 没有找到相关文章

最新更新