2016-10-15 3 views
0

私は構造体へのポインタ配列を持っていますが、それらはもはや必要なくなった時点でfree()を使用しようとしています。以下は、これらの構造体が設定されている方法です:1回C:Segfault Free()を使用しています

typedef struct { 
    SDL_Surface *sprite; 
    SDL_Rect rect; 
} Laser; 

Laser *fireLaser(char *sprite, int x, int y) 
{ 
    Laser *laser = malloc(sizeof(Laser)); 

    laser->sprite = loadSurface(sprite); 
    laser->rect.x = x; 
    laser->rect.y = y; 

    return laser; 
} 

game->playerLasers[player->laserCount++] = fireLaser("images/laser.bmp", (player->rect.x, player->rect.y); 

がもはや必要とされ、私はそれにfree()を使用しようとします。

SDL_FreeSurface(game->playerLasers[i]->sprite); 
free(game->playerLasers[i]); 

これをfree(game->playerLasers[i]);でコンパイルし、警告またはエラーは表示されません。プログラムは実行されますが、すぐにfree()が実行されると、セグメント化エラーが発生します。

私はvalgrindでプログラムを実行すると、私は奇妙なセグメンテーションフォールトを得ることはありませんが、私は一度free()次の出力を得るかは、RANです:

==2010== Invalid read of size 8 
==2010== at 0x4012D8: spawnGrunts (main.c:196) 
==2010== by 0x4013FC: updates (main.c:219) 
==2010== by 0x4016CD: main (main.c:277) 
==2010== Address 0xcfce9c0 is 0 bytes inside a block of size 32 free'd 
==2010== at 0x4C2AD90: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2010== by 0x4012FF: spawnGrunts (main.c:197) 
==2010== by 0x4013FC: updates (main.c:219) 
==2010== by 0x4016CD: main (main.c:277) 
==2010== Block was alloc'd at 
==2010== at 0x4C29BBE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2010== by 0x400E65: loadGrunt (main.c:105) 
==2010== by 0x4011FE: spawnGrunts (main.c:182) 
==2010== by 0x4013FC: updates (main.c:219) 
==2010== by 0x4016CD: main (main.c:277) 
==2010== 
==2010== Invalid free()/delete/delete[]/realloc() 
==2010== at 0x4C2AD90: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2010== by 0x4012FF: spawnGrunts (main.c:197) 
==2010== by 0x4013FC: updates (main.c:219) 
==2010== by 0x4016CD: main (main.c:277) 
==2010== Address 0xcfce9c0 is 0 bytes inside a block of size 32 free'd 
==2010== at 0x4C2AD90: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2010== by 0x4012FF: spawnGrunts (main.c:197) 
==2010== by 0x4013FC: updates (main.c:219) 
==2010== by 0x4016CD: main (main.c:277) 
==2010== Block was alloc'd at 
==2010== at 0x4C29BBE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==2010== by 0x400E65: loadGrunt (main.c:105) 
==2010== by 0x4011FE: spawnGrunts (main.c:182) 
==2010== by 0x4013FC: updates (main.c:219) 
==2010== by 0x4016CD: main (main.c:277) 

誰も私にこれにヒントを与えることができるだろう1?

+0

コード内のどこかでヒープを破損していませんか? –

+1

ポインタを使わずに 'Laser'を使わないのはなぜですか?割り当てない/解放しないことを意味しますか?結局のところ、それは小さな構造であり、問​​題なくコピーすることができます。 (たぶんあなたは構造体を複数回解放しているかもしれません) –

+0

レーザーを割り当てると、カウントが増えます: 'player-> laserCount ++'。そのレーザーを「フリー」にすると、配列内のエントリーを削除する必要があり、カウントを減らす必要があります。私はあなたがそれをやっていないと推測し、その結果、あなたは配列内にポインタを持っているということです。 – user3386109

答えて

0

valgrindでプログラムを実行すると、valgrindによって作成されたメモリ空間内で実行されているため、ほとんどの場合クラッシュしません。これはプログラムにとってより寛容です。

ノンポインタータイプを解放しようとしない限り、通常は無料でコンパイルエラーが発生しません。しかし、あなたは悪いアドレスを解放しようとしているので、実行時にクラッシュします。

私は非常に興味があるでしょう、あなたの機能を見ることに興味があります。

あなたはどこの場所にいても、アレイのサイズを把握していますか? 配列[i]を解放して使用できなくなったことを通知するには、NULLに設定しますか?

ポインタが使用できないときは、必ずポインタをNULLに設定してください。

+0

GitHub [here](https://github.com/azurepancake/space-man/blob/master/main.c)で自分のコードにリンクする方が簡単かもしれません。クリーンアップを処理しようとしている関数は 'shootLasers()'です。今、私はそれが最大に近づくと私の配列[i]を0に戻します。 – azurepancake

関連する問題