0

基本的に、ここで達成しようとしているのは、コンパイル時にサイズがわからない構造体へのポインターの配列を持つグローバル変数を持つことです。以下の例では、my_struct **tabです。最終バージョンでは、ポインターの配列を初期化するJNIメソッドを呼び出し、他のメソッドの使用のためにそれらを保持したいと思います。

残念ながら、私はCプログラマーではなく、この問題に本当に苦労しています。以下に、私がやろうとしたことを示します。明らかに、それは機能していません。建設的なフィードバックは本当に役に立ちます。

(Cコードであるはずのインクルードを誤解してすみません)

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

typedef struct {
    int tag;
} my_struct;

my_struct **tab;

void * get_pointer_to_struct() {

    my_struct * s;
    /* allocate memory */
    if ((s = (my_struct *) malloc(sizeof (my_struct))) == NULL) {
        return NULL;
    }
    return s;
}

void free_structures(int j) {
    for (int a; a < j; a++) {
        my_struct *s;
        s = (my_struct *) tab[a];

        /* free memory */
        free(s);
        tab[a] = NULL;
    }
}

void init_pointers_array(int j) {
    my_struct * temp_arr[j];
    for (int i = 0; i < j; i++) {
        temp_arr[i] = (my_struct *) get_pointer_to_struct();
        temp_arr[i]->tag = i;
    }
    tab = temp_arr;
}

int main() {
    //initialization
    init_pointers_array(10);
    //usage
    for (int a = 0; a < 10; a++) {
        if (tab[a]) {
            my_struct * str_tmp = tab[a];
            printf("Integer that you have entered is %d\n", str_tmp->tag);
        }
    }
    //free mem
    free_structures(10);
    return 0;
}
4

3 に答える 3

3

このコードはとても読めないので、わざわざ読んでくれる人がいることに驚いています。次のガイドラインに従うと、すべての問題が解決されます。

  • 生の配列の代わりに std::vector (または同様の配列クラス) を使用します
  • 必要がない場合は動的割り当てを使用しないでください。ただし、malloc の代わりにnewを使用する場合は、
  • 動的割り当てを使用する場合は常に、オブジェクトを所有し、RAII 原則に従うクラス内で使用してください。
  • グローバル変数を使用しない
于 2013-01-10T23:52:16.047 に答える
1
my_struct * temp_arr[j];

それから

tab = temp_arr;

間違っています。(*修飾子の配置がひどく、コードの可読性を大幅に低下させる余分なキャストがあるだけでなく)temp_arrayローカル自動配列であるため、関数が戻ったときに割り当てが解除されます。その後、そのアドレスで何かを行うと、未定義の動作が発生します。代わりに、構造体用にメモリを使用することをお勧めしますmalloc()(キャストは、コードをC ++で使用できるようにするためにのみ存在します。Cでは、冗長なタイプキャストを作成することは強くお勧めしません)。

my_struct **tab;

tab = (my_struct **)malloc(sizeof(tab[0]) * number_of_structs);

int i;
for (i = 0; i < number_of_structs; i++) {
    tab[i] = (my_struct *)malloc(sizeof(tab[0][0]));
}

そしてそれを解放するために:

int i;
for (i = 0; i < number_of_structs; i++) {
    free(tab[i]);
}

free(tab);
于 2013-01-10T23:39:31.673 に答える
0

いくつかのポイント:

  • get_pointer_to_structの結果を単純に返すことができますmalloc。への余分なキャストを避けるために、署名を変更しmy_struct*ます。
  • temp_arrayスタック上に作成されるため、終了時に存在しなくなりinit_pointers_arrayます。mallocそれも。これはあなたの最大の問題です。
  • これは一般的にです。多くの余分な作業を行うため、コードがひどく肥大化します。冗長なキャストや不要な変数を避けるようにしてください。
于 2013-01-10T23:41:39.067 に答える