0

次のような短いmallocを使用しようとしています

typedef union _SOME_STRUCT_ {

   struct {

     USHORT u:4;
     USHORT v:4;
     USHORT w:4;

   } x;

   USHORT word;

} SOME_STRUCT, *PSOME_STRUCT;

PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));

if (p) {

    p->x.u = 0;
}

free (p); // **** RANDOMLY CRASHING HERE ****

私は数日間デバッグしていますが、無知です。

注(編集済み): Linux、および gcc バージョン 3.4.6 20060404


VALGRIND を使用して見つかった問題

しかし、それから、私の仲間の開発者がそのような状況を認識できるように、ここに文書化したいと思います...

私は実際に構造を次のように定義しました

typedef union _SOME_STRUCT_ {

   struct {

     USHORT u:4;
     USHORT v:4;
     USHORT w:4;

   } x;

   USHORT word;

} ALBUM, *PALBUM;

そして、私が定義したコードの他の場所

#define ALBUM "album"

そのため、sizeof (ALBUM) は typedef ではなく #define 値を参照していたため、問題が発生しました。

私を驚かせるのは、

これはCで許可されていますか?


4

8 に答える 8

3

プログラムをvalgrindに渡すようにしてください。これはオープン ソース プログラムであり、完全に無料です。問題がどこにあるかを確認するのに役立つ可能性があります。デバッグ シンボルを使用してコンパイルすることを忘れないでください: gcc -g [etc] 。

この助けを願っています..

于 2009-05-13T01:22:40.577 に答える
3

このバージョンのコードは私にとってはうまくいきます。

#include <stdio.h>
#define USHORT unsigned short

typedef union _SOME_STRUCT_ {
    struct {
        USHORT u:4;
        USHORT v:4;
        USHORT w:4;
    } x;
    USHORT word;
} SOME_STRUCT, *PSOME_STRUCT;

int
main(int c, char *argv[])
{
    PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));

    if (p) {
        p->x.u = 0;
    }

    free (p); // **** Properly exiting after this ****
}

これは Windows XP 上の Cygwin からの GDB デバッグです。

(gdb) p/x sizeof(PSOME_STRUCT)
$1 = 0x4
(gdb) p/x sizeof(p)
$2 = 0x4
(gdb) p/x sizeof(*p)
$3 = 0x2
(gdb) n
23              if (p) {
(gdb) p/x *p
$4 = {x = {u = 0xc, v = 0x4, w = 0x3}, word = 0x534c}

$4 の値は無視してください。データは初期化されていません。プログラムは正常に終了しました。

これらの行以外にコードに何かありますか?

編集: そして、free(0); 有効な操作です。

于 2009-05-13T02:11:34.527 に答える
2

アライメントの問題かもしれません。次のようなことをすると、まだクラッシュしますか?

   struct {
     USHORT u:4;
     USHORT v:4;
     USHORT w:4;
     USHORT  :4;
   } x;
于 2009-05-13T01:15:31.657 に答える
2

問題はコードではなく、前または別のスレッドで発生している何かです。

クラッシュが止まるまでプログラムのセクションを減らしてから、これを引き起こしているセクションがわかるまで段階的に追加します。OS/プラットフォームによっては、valgrind/_crtdebug などのメモリ チェック ツールを試すこともできます。

于 2009-05-13T02:22:02.260 に答える
1

malloc が成功したかどうかを確認せずに無条件に free() を呼び出しているため、malloc が失敗し、p が NULL ポインターである場合は、free(NULL) を呼び出しています。

フリーを if (p) ブロック内に移動します。

これはクラッシュの原因ではない可能性があり、メモリの制約がなければそうあるべきではありませんが、それでもバグです。

後で追加: http://www.opengroup.org/onlinepubs/009695399/functions/free.htmlに従って、free(NULL) は明示的に許可されています。

于 2009-05-13T03:19:45.577 に答える
1

この問題がデバッグ可能な場所で発生している場合は、memcheck を呼び出してデバッグ セッションを開始できます。

メモリのクラッシュの原因は、ほとんどの場合、同じポインターを 2 回ヒープまたは解放することです。

于 2009-05-13T02:28:59.390 に答える
1

malloc と free の間で何かをしている場合、誤って別の配列をオーバーランし、自分のスタックを破損する可能性があります

('p' がたまたまレジスタになく、静的に割り当てられた配列をオーバーランし、スタック上の 'p' が格納されている場所にヒットした場合、後でランダムながらくたを解放しようとするため、segfault が発生します) )

于 2009-05-13T03:25:43.240 に答える
0

if に free(p) を入れるとどうなりますか? たぶん(ありそうもない)mallocが失敗しています...

于 2009-05-13T01:14:07.700 に答える