学校では、マップをセルで初期化する必要があります。 Valgrindでコードを分析しているときに、いくつかの問題が発生しました。 私が使用した初期化関数は、以前に動作しましたが、2つの追加の整数ポインタと整数を追加した後に機能しなくなりました。メモリは動的に割り振られていて、以前にも存在していた部分にバグが現れます。発生したエラーは以下の通りであった:構造体コードを追加した後、Valgrindが無効になります。
worldmap* initialize_map(game_settings* settings)
{
int maxplayers = 10;
int rows = settings->rows;
int cols = settings->cols;
worldmap* world = malloc(sizeof(worldmap)); //free in cleanup_map
if(world != NULL)
{
world->rows = rows;
world->cols = cols;
world->map = malloc(sizeof(cell)*rows*cols); //free in cleanup_map
for(int i = 0; i < rows;i++)
{
for(int j = 0; j < cols;j++)
{
cell* cell = index_map(world, j, i); //cell* is world->map + offset
cell->type = CELL_DIRT;
cell->owner = 0;
}
}
world->players = 0;
world->score = NULL; //NULL pointer, since this pointer set in a later function
world->playerturns = NULL; //NULL pointer, since this pointer set in a later function
return world;
}
else{printf("No world found.\n");}
}
このinitialize_map()
コードへの追加は、次のとおりです:int maxplayers
、world->players
、world->score
とworld->playerturns
、残りのコード
==4877== Invalid write of size 4
==4877== at 0x401723: initialize_map (list.c:312)
==4877== by 0x400B99: main (initialization.c:14)
==4877== Address 0x550deb8 is 0 bytes after a block of size 2,584 alloc'd
==4877== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4877== by 0x4016EA: initialize_map (list.c:306)
==4877== by 0x400B99: main (initialization.c:14)
==4877==
==4877== Invalid write of size 4
==4877== at 0x40172D: initialize_map (list.c:313)
==4877== by 0x400B99: main (initialization.c:14)
==4877== Address 0x550debc is 4 bytes after a block of size 2,584 alloc'd
==4877== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4877== by 0x4016EA: initialize_map (list.c:306)
==4877== by 0x400B99: main (initialization.c:14)
==4877==
valgrind: m_mallocfree.c:277 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
初期化コードは以下のとおりです。これらの追加なしで、valgrindで実行するときに有効でした。このコードでindex_map()
はcell* w->map+y_offset + x_offset
を返します。これは整数値と整数ポインタを別々に割り当てることと関連しているかもしれません(無効な書き込みエラーを出した部分でこれをやろうとしました。 ):
world->map = malloc(sizeof(cell)*rows*cols);
for(int i = 0; i < rows;i++)
{
for(int j = 0; j < cols;j++)
{
cell* cell = index_map(world, j, i); //cell8 is world->map + offset
cell->type = malloc(sizeof(celltype);
*(cell->type) = CELL_DIRT;
cell->owner = malloc(sizeof(int);
*(cell->type) = 0;
}
}
このコードをコンパイルしようとすると、folllowingのエラーが表示されます。
"invalid type argument of unary ‘*’ (have ‘unsigned int’) *(cell->type) = 0;
"
これらは、私が使用した構造体です:
セル構造体:
typedef struct{
celltype type;
unsigned int owner;
} cell;
世界地図の構造体:
typedef struct
{
cell* map;
unsigned int rows;
unsigned int cols;
int players;
int* score;
int* playerturns;
} worldmap;
セル構造体は変わらず、世界地図の構造体は、以前はcell* map
、unsigned int rows
とunsigned int cols
で構成しました。
EDIT index_mapコード:
cell* index_map(worldmap* w, int x, int y)
{
cell* place;
place = w->map + x*w->cols + y;
return place;
}
オリジナルのバグのソースであると思われる 'index_map'cosのコードを含めることができますか? –