2017-04-06 41 views
1

對於學校,我必須用單元格初始化映射。 在與Valgrind分析我的代碼時,我遇到了一些問題。 我以前使用的初始化函數工作,但添加兩個額外的整數指針和一個整數後停止運作。內存是動態分配的,並且該錯誤出現在之前也存在的部分中,這讓我難倒了。發生的錯誤是如下:在添加結構代碼後,Valgrind無效寫入

==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. 

初始化代碼如下:

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 maxplayersworld->playersworld->scoreworld->playerturns,將其餘代碼在valgrind中運行時是有效的,沒有這些添加。在此代碼index_map()返回cell* w->map+y_offset + x_offset

我在其他幾個職位讀,這可能有這樣的seperatly再次分配的整數值和整數指針做(我試圖做到這一點上給了無效的寫入錯誤的部分):

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* mapunsigned int rowsunsigned 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; 
} 
+0

你能否包含'index_map' cos代碼,這似乎是原始錯誤的來源。 –

回答

0

valgrind錯誤基本上是說你正在訪問超出你分配的地圖範圍的內存。現在你已經包含了index_map函數,爲什麼呢也很明顯。

想象一下,如果你的地圖是5列2行 - 所以10個單元的大小。這意味着最x和y可以是4和1你的函數計算4 * 5 + 1返回21單元...的代碼去解決它應該是這個

place = w->map + x*w->rows + y; 

place = w->map + x + y*w->cols; 

這會給你4 * 2 + 1或4 + 1 * 5 =第9個單元格。

至於你提到的其他問題,你不需要爲這些值分配內存,因爲它們不是指針。例如

cell->owner = malloc(sizeof(int); 

cell->owner是一個unsigned int,所以你可以做cell->owner = 10;給它分配一個值。

以及你不需要兩次去引用它們來使用它們 - *(cell->owner)是矯枉過正,只需要cell->owner

1
  • cell->type = malloc(sizeof(celltype);類型不是指針。你自己是否爲cell本身?什麼是index_max
  • cell* cell對類型和變量使用相同的名稱並不是一個好主意。
  • *(cell->type)是無稽之談。使用cell->type(*cell).type(前者更具可讀性)。
  • 總的來說,你在幾個似乎沒有任何意義的地方使用malloc,你可以使用普通變量。
  • 你在哪裏free()所有這一切?如果你不這樣做,Valgrind可能會感到不安。

依此類推。