【发布时间】:2014-01-04 23:18:41
【问题描述】:
在我的程序中,我将vector<vector<int> > 复制到另一个这样的:
#include <vector>
#include <cstdlib>
#include <cmath>
typedef std::vector<std::vector<int> > VVector;
VVector mix_genome(VVector mix_genome,
VVector g1,
VVector g2,
int gene_length)
{
VVector gbuilt = g1; // valgrind gets angry at this a bit...
for(int i = 0; i < 30; i++)
{
int syngamete_chance = std::floor(std::rand() % 100);
if(syngamete_chance <= 50)
{
gbuilt[i] = g2[i];
}
}
int mutation_chance = floor(rand() % 100);
if(mutation_chance <= 3)
{
int gene_num = floor(rand() % 30);
int act_num = floor(rand() % gene_length+1);
int rand_act = floor(rand() % 8);
gbuilt[gene_num][act_num] = rand_act;
}
return gbuilt;
}
这在运行程序大约 3 分钟后(每隔一段时间调用此函数)会导致内存访问错误。 Valgrind 为我提供了有关此功能的以下信息:==31557== Invalid write of size 4 和 Address 0x10207e360 is 0 bytes after a block of size 16 alloc'd
如果我禁用该函数并且不调用它,程序似乎不会崩溃。 GDB 给了我malloc: *** error for object 0x1068a6878: incorrect checksum for freed object - object was probably modified after being freed.。回溯表明它来自 operator=:
#13 0x000000010000f8d4 in std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::operator= (this=0x7fff5fbfe780, __x=@0x7fff5fbfeb50) at vector.tcc:140
我认为这也会导致其他错误,但我不确定。
编辑:
这是我的 Tick() 函数,它显然也是导致此错误的原因。
int Creature::Tick() {
if(!dead) {
food--;
timeLasted++;
step++;
if(step > maxStep) {
step = 0;
}
if(cooldown > 0) {
cooldown--;
}
if(xpos > 178) {
events[EVENT_RIGHT_SEEN_EDGE_OF_SCREEN] = true;
}
else if(xpos < 20) {
events[EVENT_LEFT_SEEN_EDGE_OF_SCREEN] = true;
}
if(ypos > 179) {
events[EVENT_BOTTOM_SEEN_EDGE_OF_SCREEN] = true;
}
else if(ypos < 20) {
events[EVENT_TOP_SEEN_EDGE_OF_SCREEN] = true;
}
events[EVENT_NOTHING_HAPPENED] = true;
for(int z = 0; z < NUM_EVENTS-1; z++) {
if(events[z]) {
events[EVENT_NOTHING_HAPPENED] = false; // events[z] is true so something happened
}
}
for(int i = 0; i < NUM_EVENTS-1; i++) { // last event should always be "nothing happened"
if(events[i]) {
Action(genome[i][step]); // this has been ided by valgrind: invalid read size 4
events[i] = false;
}
}
if(!fighting && events[EVENT_NOTHING_HAPPENED]) {
Action(genome[EVENT_NOTHING_HAPPENED][step]);
}
if(food < 0)
food = 0;
if(food > maxFood)
food = maxFood;
if(food == 0) {
lifetime -= 5;
}
if(xpos > 200-bodySize) {
xpos = 200-bodySize;
}
else if(xpos < 0) {
xpos = 0;
}
if(ypos > 200-bodySize) {
ypos = 200-bodySize;
}
else if(ypos < 0) {
ypos = 0;
}
}
return timeLasted;
}
【问题讨论】:
-
valgrind 在源代码的哪一行显示错误?
-
您可能在其他地方有堆损坏/未定义行为
-
@JamesMcLaughlin 它不显示函数代码本身,而是显示对函数的调用,即:
new_genome = mix_genome(creatures[breedCreature1].genome, creatures[breedCreature2].genome, creatures[body].bodySize*2); -
@sehe 我怎样才能知道如何/在哪里?编辑 - 感谢您提高代码可读性
-
如果 valgrind 没有告诉你(我们不知道,因为你显示的信息太少),clang++ 有一个地址清理器/未定义的行为检测标志