2017-04-06 38 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可能会感到不安。

依此类推。