2

問題を切り分けようとしてきた問題を単純化しましたが、役に立ちません。

メモリを表す 2 次元の char 配列があります。そのメモリのシミュレーションへの参照を関数に渡したいです。メモリの内容をテストする関数では、メモリを反復処理して、各行の内容を出力したいだけです。

プログラムが最初の行を出力した後、seg fault が発生します。

私のプログラムは次のとおりです。

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

void test_memory(char*** memory_ref)  {

    int i;
    for(i = 0; i < 3; i++)  {
        printf("%s\n", *memory_ref[i]);
    }
}

int main()  {
    char** memory;
    int i;
    memory = calloc(sizeof(char*), 20);
    for(i = 0; i < 20; i++)  {
        memory[i] = calloc(sizeof(char), 33);
    }

    memory[0] = "Mem 0";
    memory[1] = "Mem 1";
    memory[2] = "Mem 2";

    printf("memory[1] = %s\n", memory[1]);

    test_memory(&memory);

    return 0;
}

これにより、出力が得られます。

memory[1] = Mem 1
Mem 0
Segmentation fault

プログラムを変更し、memory_ref を逆参照して関数内のメモリのローカル バージョンを作成すると、正しい出力が得られます。

そう:

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

void test_memory(char*** memory_ref)  {

    char** memory = *memory_ref;
    int i;
    for(i = 0; i < 3; i++)  {
        printf("%s\n", memory[i]);
    }
}

int main()  {
    char** memory;
    int i;
    memory = calloc(sizeof(char*), 20);
    for(i = 0; i < 20; i++)  {
        memory[i] = calloc(sizeof(char), 33);
    }

    memory[0] = "Mem 0";
    memory[1] = "Mem 1";
    memory[2] = "Mem 2";

    printf("memory[1] = %s\n", memory[1]);

    test_memory(&memory);

    return 0;
}

次の出力が得られます。

memory[1] = Mem 1
Mem 0
Mem 1
Mem 2

これは私が望むものですが、メモリのローカルバージョンを作成することは役に立ちません。関数から元のメモリの値を変更できるようにする必要があるためです。

2 回目にセグ フォールトが発生する理由がわかりません。アドバイスをいただければ幸いです。

どうもありがとう

ジョー

4

3 に答える 3

4

試す:

printf("%s\n", (*memory_ref)[i]);

現在のバージョンは同等です

*(*(memory_ref + i));

これは、[]演算子の優先順位が dereference よりも高いためです*。つまり、iが 0 より大きい場合、char***一時的なメモリの後にメモリを読み込もうとすることを意味します。memory_ref

2 番目のバージョンは等しい(*memory_ref)[i]です。これは、正しいメモリにインデックスを付けることを意味します。

編集:最初の反復で機能する理由は次のとおりです。

*(*(memory_ref + 0)) == *((*memory_ref) + 0)
于 2010-04-29T11:19:44.807 に答える
2

これは優先順位の問題のようです。[] が最初に評価され、* が 2 番目に評価されます。必要なのは、最初のコード例として次のようなものです...

printf("%s\n", (*memory_ref)[i]);
于 2010-04-29T11:24:35.237 に答える
1

クイックフィックスは使用することです

printf("%s\n", (*memory_ref)[i]);

しかし、回線に問題があると思われます

 memory[0] = "Mem 0";

これらは文字列「Mem 0」をメモリ配列にコピーしません。それらは、memory[i] が文字列を指すようにします。

strncpyを使用して明示的にデータをコピーする必要があります

例 char s = "Mem 0"; strncpy( memory 1 , s, max( strlen(s) + 1, 29) ) // 最大 30= (29 文字 + '\0' は、割り当てた行の長さです - これを定数として #define する方が良いでしょう

于 2010-04-29T11:50:34.647 に答える