5

私より賢い人が、なぜ次のコードセグメントに障害があるのか​​説明してもらえますか?参照によるメモリの割り当てに問題はありませんが、何かを割り当てようとしたり、参照によって解放しようとすると、セグメンテーション違反が発生します。

ポインタと参照による受け渡しについての基本的な概念が欠けていると確信しています。うまくいけば、いくつかの光を当てることができます。

#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;
}
4

3 に答える 3

8

問題の1つのセットはここにあります:

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));
}

少なくとも他の機能はOKである可能性があります。は正しく記述され、呼び出されますが、ポインタからfillMatrix()3番目を失うことで簡略化できます。*

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);   
于 2012-04-07T04:43:32.870 に答える
4

間接参照の有効活用。フォーマットとの一貫性を保つようにしてください。読みやすさが向上し、エラーが減少します。例えば

関数呼び出し:

    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]
于 2012-04-07T04:41:44.870 に答える
0

関数からポインタを返すことは、おそらくメモリを割り当てるためのより良い方法です。

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);
    */
}
于 2012-04-07T07:02:54.203 に答える