5

有人可能比我更聪明地向我解释为什么下面的代码段出错?通过引用分配内存没有问题,但只要我尝试通过引用分配任何内容或释放内存,就会发生段错误。二维动态数组的分配和传递参考C

我敢肯定,我错过了一些关于指针和通过引用传递的基本概念,希望能够抛弃一些光。

#include <stdlib.h> 
#include <stdio.h> 

void allocateMatrix(float ***); 
void fillMatrix(float ***); 
void freeMatrix(float **); 

int main() { 
    float **matrix; 

    allocateMatrix(&matrix);  // this function calls and returns OK 
    fillMatrix(&matrix);   // this function will segfault 
    freeMatrix(matrix);    // this function will segfault 

    exit(0); 
} 

void allocateMatrix(float ***m) { 
    int i; 
    m = malloc(2*sizeof(float*)); 
    for (i = 0; i < 2; i++) { 
     m[i] = malloc(2*sizeof(float)); 
    } 
    return; 
} 

void fillMatrix(float ***m) { 
    int i,j; 
    for (i = 0; i < 2; i++) { 
     for (j = 0; j < 2; j++) { 
      (*m)[i][j] = 1.0;  // SEGFAULT 
     } 
    } 
    return; 
} 

void freeMatrix(float **m) { 
    int i; 
    for (i = 0; i < 2; i++) { 
     free(m[i]);     // SEGFAULT 
    } 
    free(m); 
    return; 
} 
+0

我其实有点惊讶,编译。 “void allocateMatrix(&m)”可能不会像预期的那样将m输入为float **。另外,C中的引用与C++中的引用不同。 – Corbin 2012-04-07 04:08:25

+0

为什么'freeMatrix'等签名在声明和定义时有所不同? – keety 2012-04-07 04:14:47

+0

keety,科尔宾:对不起复制粘贴失败,修复它 – holocron 2012-04-07 04:37:43

回答

8

一组的问题是在这里:

void allocateMatrix(float ***m) { 
    int i; 
    m = malloc(2*sizeof(float*)); 
    for (i = 0; i < 2; i++) { 
     m[i] = malloc(2*sizeof(float)); 
    } 
    return; 
} 

您需要分配到*m以将信息返回到调用代码,并且您还需要在循环中分配给(*m)[i]

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

至少有一个机会,其他功能都可以。该fillMatrix()写入和正确调用,虽然它可以通过指针失去第三*被简化:

void fillMatrix(float **m) 
{ 
    for (int i = 0; i < 2; i++) 
    { 
     for (int j = 0; j < 2; j++) 
      m[i][j] = 1.0;   
    } 
} 

这可能是最好的三指针传递给freeMatrix(),这样就可以在零的指针调用函数:

void freeMatrix(float ***m) 
{ 
    for (int i = 0; i < 2; i++) 
     free((*m)[i]); 
    free(*m); 
    *m = 0; 
} 

然后调用变为:

allocateMatrix(&matrix); 
fillMatrix(matrix); 
freeMatrix(&matrix); 
+0

谢谢Jonathan,这非常有道理。 – holocron 2012-04-07 04:51:40

3

良好的间接使用。只是尝试与格式一致。它提高了可读性并减少了错误。例如

函数调用:

allocateMatrix &matrix 
    fillMatrix &matrix 
    freeMatrix &matrix 

声明

void allocateMatrix float ***m 
void fillMatrix float ***m 
void freeMatrix float ***m 

处理

(*m)[i] = malloc(2 * sizeof(float)) 
    (*m)[i][j] = 1.0 
    free (*m)[i] 
+0

这是有道理的,我现在试着实现。 – holocron 2012-04-07 04:50:48

0

从你的乐趣指针返回ction可能是更好的分配内存的方式:

float **allocateMatrix() { 
    int i; 
    float **m; 

    m = malloc(2*sizeof(float *)); 
    for (i = 0; i < 2; i++) { 
     m[i] = malloc(2*sizeof(float)); 
    } 

    return m; 
} 

int main() { 
    float **m; 

    m = allocateMatrix(); 

    /* do other things 
     fillMatrix(matrix); 
     freeMatrix(&matrix); 
    */ 
}