私はあなたのコードに現れるポインターの理解の深刻な欠如を恐れています。問題が発生する場所を明確にするために、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;
です。
そのような行動は、以下の深刻な問題につながります。
- 4行目でメモリを割り当てました。次に、このポインタをスタック変数へのポインタで上書きします。したがって、割り当てられたメモリをもう解放することはできません==>メモリリーク
- スタック変数への新しく割り当てられたポインターは、スコープを終了した後に無効になり、未定義の動作を引き起こす可能性があります。
- 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;
}