-2

以下のコードがあります。以下のコードでは、値5が変数a(つまりabc.a) に格納されます。cしかし、 (つまり)の値を初期化したいと思いますabc.c。どうやってするか?私の要件は、 ではcなく のデータを入力することですa

typedef struct abc
{
    int a;
    int b;
    int c;
}abc;
typedef struct def{
    int *ptr;
    abc strpt;
}def;
typedef struct xyz{
int *pointer;
}xyz;
int main()
{
    int *temp, tmp;
    abc* ab;
    tmp = 5;
    temp = &tmp;
    ab = (abc*)malloc(sizeof(abc));
    xyz *x = (xyz*)malloc(sizeof(xyz));
    def *de = (def*)malloc(sizeof(def));
    x->pointer = (xyz*)temp;
    ab = (abc*)x->pointer;


    return 0;
}

私を助けてください。

4

3 に答える 3

2

私はあなたのコードに現れるポインターの理解の深刻な欠如を恐れています。問題が発生する場所を明確にするために、1行ずつ分析してみましょう。

上記の型宣言を想定して、簡単に参照できるようにステートメントに番号を付けました。

int main()
{
    int *temp, tmp;
    abc* ab;
    /* 1 */ tmp = 5;
    /* 2 */ temp = &tmp;
    /* 3 */ ab = (abc*)malloc(sizeof(abc));
    /* 4 */ xyz *x = (xyz*)malloc(sizeof(xyz));
    /* 5 */ def *de = (def*)malloc(sizeof(def));
    /* 6 */ x = (xyz*)temp;
    /* 7 */ ab = (abc*)x;

    return 0;
}

まず第一に、3、4、5で割り当てられたメモリをクリーンアップすることは決してありません。単純なテストプログラムであっても、常にこのようなことを行う必要があります。

最初の問題は6行目で、int型(メモリ内で4バイト)のオブジェクトへのポインタをxyz型(メモリ内で4バイトまたは8バイト、異なる型)の構造体へのポインタに盲目的にキャストします。ここで行うことは、を書くための複雑な方法x = (xyz*)&tmp;です。

そのような行動は、以下の深刻な問題につながります。

  1. 4行目でメモリを割り当てました。次に、このポインタをスタック変数へのポインタで上書きします。したがって、割り当てられたメモリをもう解放することはできません==>メモリリーク
  2. スタック変数への新しく割り当てられたポインターは、スコープを終了した後に無効になり、未定義の動作を引き起こす可能性があります。
  3. 6行目以降のxの要素への書き込み試行は、要素のサイズの不一致の可能性があるため、スタックの破損(したがって未定義の動作)につながる可能性があります。

7行目までに、同じ問題が再び発生し、さらに悪化します。推定sizeof(abc)はおそらく12バイトです。この行の後にabcの要素にアクセスすると、スタックが再び破損する可能性があります。

私はまだあなたが本当に探しているものを理解していませんが、ポインタを介して構造要素を「初期化する」必要がある場合は、いくつかの方法があります。

構造体が不明な場合は、次のように実行できます。abc * ab = malloc(sizeof(abc));

if (ab != NULL) {
    ab->c = 5;

    // -- do other stuff

    free(ab); ab = NULL;
}

要素'c'へのポインタが必要な場合は、次のように実行できます。

int * c_ptr = NULL;
abc * ab = malloc(sizeof(abc));

if (ab != NULL) {
    c_ptr = &(ab->c);
    *c_ptr = 5;

    //-- do other stuff
    free(ab); ab = NULL;
}
于 2013-01-23T13:46:48.867 に答える
0

あなたはこれを求めていますか:

abc s;
s.c = 5;

それはc5 になります。

abc s = {0,0,5};

つまり、最初の 2 つのメンバーは に初期化され0、3 番目のメンバー ( c) は に初期化され5ます。

または、ポインタがある場合は、これを行うことができます:

abc *p = malloc(etc);
p->c = 5;

ただし、ポインターとmalloc. 本当に必要なときに使用してください。あなたのコードでは、それが必要な理由がわかりません。ポインターではなく、自動変数を使用します。

于 2013-01-23T13:17:44.010 に答える
0

必要なものを取得するには、main() に戻る前にこれを追加する必要があると思います。

ab->c = *(x->pointer);
于 2013-01-23T13:44:51.993 に答える