0

こんにちは、すべての Malloc 呼び出し (および後続の malloc チェック) を次のような 1 つのルーチンに移動して、コードを整理しようとしています。

int Malloc2D(int n, int m, double** array_ptr) {

array_ptr = (double**) malloc(n * sizeof(double*));
if (array_ptr == NULL) {
    std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
    return -1;
}
for (int i = 0; i < n; i++) {
    array_ptr[i] = (double*) malloc(m * sizeof(double));
    if (array_ptr[i] == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
}

return 0;
}

しかし、main() では、次のようなことを行います。

double** test;
if(Malloc2d(10, 20, test) == -1) return -1;

次に、配列をメインで使用しようとすると、segfault が発生しますか? 誰でもアイデアはありますか?ジャック

4

4 に答える 4

2

a を渡しているdouble **array_ptrため、関数の外側のポインターは変更されません。

C++では、参照にすることで修正できます(newC++であるため、を使用します)

int Malloc2D(int n, int m, double**& array_ptr) {

array_ptr = new double*[n]);
if (array_ptr == NULL) {
    std::cout << "ERROR! new failed on line " << __LINE__ << "..." << std::endl;
    return -1;
}
for (int i = 0; i < n; i++) {
    array_ptr[i] = new double[m];
    if (array_ptr[i] == NULL) {
        std::cout << "ERROR! new failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
}

return 0;
}

または、C スタイルの方法で、別のポインター間接化を使用することもできます (&test呼び出しコードで を使用して のアドレスを渡しますdouble ** test)。

int Malloc2D(int n, int m, double*** array_ptr) {

*array_ptr = (double**) malloc(n * sizeof(double*));
if (array_ptr == NULL) {
    std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
    return -1;
}
for (int i = 0; i < n; i++) {
    (*array_ptr)[i] = (double*) malloc(m * sizeof(double));
    if ((*array_ptr)[i] == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
}

return 0;
}

または、最初に配列へのポインターを返すだけでもかまいませんが、これには呼び出しコードにいくつかの小さな変更が必要になります。

double** Malloc2D(int n, int m) {

double** array_ptr;
array_ptr = (double**) malloc(n * sizeof(double*));
if (array_ptr == NULL) {
    std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
    return NULL;
}
for (int i = 0; i < n; i++) {
    array_ptr[i] = (double*) malloc(m * sizeof(double));
    if (array_ptr[i] == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return NULL;
    }
}

return array_ptr;
}
于 2013-07-02T16:59:34.803 に答える
1

C と C++ は値渡しです。したがって、関数の内部に
加えられた変更は、関数の外部には表示されません。array_ptrMalloc2D

テストへのポインターを渡し、その値を変更します。
(これはトリプルポインターにつながります。混乱しますが、管理不能ではありません)

int Malloc2D(int n, int m, double*** pOutput)
{
    double** array_ptr
    array_ptr = (double**) malloc(n * sizeof(double*));
    if (array_ptr == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
    for (int i = 0; i < n; i++) {
        array_ptr[i] = (double*) malloc(m * sizeof(double));
        if (array_ptr[i] == NULL) {
            std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
            return -1;
        }
    }

    *pOutput = array_ptr;
    return 0;
}

次に、関数を使用するには、次のアドレスを渡しますtest

double** test;
if(Malloc2d(10, 20, &test) == -1) return -1;
于 2013-07-02T16:53:05.347 に答える
1

次に、メインで配列を使用しようとすると、セグメンテーション違反が発生します

問題は、array_ptr値によって渡されているため、変更していないことです。考えられる解決策の 1 つは、参照渡しすることです。

int Malloc2D(int n, int m, double** &array_ptr)
                                    ^
于 2013-07-02T16:55:52.640 に答える