2

私は以下を理解しようとしています.これら3つの関数呼び出しがどのように問題なく動作しているか.構造体のポインターの sizeof で malloc を呼び出し、3 回目にそれを出力します。両方とも問題なく動作する方法は? 2 番目の malloc は 2*2*int=16 バイトのサイズを割り当て、3 番目の malloc は 2*pointer=8 を割り当てます。また、pt2 を解放しようとすると、コア ダンプが発生します。これは、Linux で C と gcc を使用している場合です。

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

struct test{
 int field1; 
 int field2;  
};


struct test func(int a, int b) {
 struct test t;
 t.field1 = a;
 t.field2 = b;
 return t;
}

  int main()
{

struct test t;


struct test  pt[2];
pt[0] = func(1,1);
pt[1] = func(2,2);
printf("%d %d\n", pt[0].field1,pt[0].field2);
printf("%d %d\n", pt[1].field1,pt[1].field2);

printf("\n");

struct test *pt1;
pt1 = malloc(sizeof(struct test) * 2);
pt1[0] = func(2,2);
pt1[1] = func(3,3);
printf("%d %d\n", pt1[0].field1,pt1[0].field2);
printf("%d %d\n", pt1[1].field1,pt1[1].field2);
printf("\n");


struct test *pt2;
pt2 = malloc(sizeof(struct test*) * 2);
pt2[0] = func(4,4);
pt2[1] = func(5,5);
printf("%d %d\n", pt2[0].field1,pt2[0].field2);
printf("%d %d\n", pt2[1].field1,pt2[1].field2);

free(pt1);
free(pt2);// I'm getting core dump when trying to free pt2

}

出力は以下です

1 1
2 2

2 2
3 3

4 4
5 5
4

2 に答える 2

3
pt1 = malloc(sizeof(struct test) * 2);

このステートメントは正しいです。

pt2 = malloc(sizeof(struct test*) * 2);

このステートメントは間違っています。式で間違った型を使用するためsizeof、間違った量のメモリが割り当てられます。この問題を正確に回避するのsizeof(*var)ではなく、使用するのが一般的な方法です。sizeof(type)

pt2 = malloc(sizeof(*pt2) * 2);

あなたのような 32 ビット プラットフォームでは、欠陥のある malloc が必要なメモリ量の半分しか割り当てないため、への割り当てp2[1]は未定義の動作を引き起こします。プログラムは、所有していないメモリに書き込みます。これは C であるため、ランタイム エラー チェックはほとんどありません。すぐにクラッシュするのではなく、malloc されたブロックの隣のメモリにあるものを上書きすることがよくあります。

バッファー オーバーランはサイレント キラーです。あなたが上書きしたものを誰が知っていますか?それは本当に何でもかまいません。pt2 を解放しようとすると、コア ダンプがトリガーされるのは当然のことです。C ではポインター エラーは厄介です。なぜなら、プログラムが最終的にクラッシュする前にしばらく足を引きずることがよくあるからです。クラッシュするコードが必ずしもバグの場所であるとは限りません。

于 2012-12-20T02:59:56.047 に答える
1

に十分なスペースを割り当てていませんpt2。ステートメント:

pt2 = malloc(sizeof(struct test*) * 2)

構造体への 2 つのポインターにスペースを割り当てるだけで、構造体自体に十分なスペースがありません。

pt2配列の境界を超えて書いています。これは未定義の動作であり、あなたの場合は でクラッシュしfreeます。これがより複雑なプログラムの一部である場合、この種の問題はさまざまな種類のメモリ破損を引き起こす可能性があります...

于 2012-12-20T03:02:32.950 に答える