C ++ - 双重免费或腐败 - 我无法找到原因

时间:2015-01-09 19:10:17

标签: c++ debugging c++11 memory-management valgrind

我用softmax动作选择实现了强化学习算法Actor Critic。我的状态空间是一个大小为xmax x ymax的网格,目标位于中间。 我将它实现为结构元素的向量:

struct stateAction{
    double up, down, right, left, sv;
};

这样每个网格点都具有所有移动(上,下,右,左)的值和actor评论家的状态值。要访问它们,我使用:

stateAction &Environment::access(int x, int y) {
    return this->matrix.at(y * this->xmax + x);
}

我用于其他学习算法的循环以相同的方式工作:

while (e.position != e.goal) {
    double r = distribution(generator);    //create random number to choose move
    std::string move = e.softmax(0.2 , r);
    int tmpx = e.position[0];
    int tmpy = e.position[1];
    e.performAction(move);
    int newx = e.position[0];
    int newy = e.position[1];
    if (move == "up") {
        e.access(tmpx, tmpy).up += alpha * (e.getReward(newx, newy) + gamma * e.access(newx, newy).sv - e.access(tmpx, tmpy).sv);
            } 
    else if (move == "right") {
                e.access(tmpx, tmpy).right += alpha * (e.getReward(newx, newy) + gamma * e.access(newx, newy).sv - e.access(tmpx, tmpy).sv);
            } 
    else if (move == "down") {
                e.access(tmpx, tmpy).down += alpha * (e.getReward(newx, newy) + gamma * e.access(newx, newy).sv - e.access(tmpx, tmpy).sv);
            } 
    else if (move == "left") {
                e.access(tmpx, tmpy).left += alpha * (e.getReward(newx, newy) + gamma * e.access(newx, newy).sv - e.access(tmpx, tmpy).sv);
            }
    e.access(tmpx, tmpy).sv += beta * (e.getReward(newx, newy) + gamma * e.access(newx, newy).sv - e.access(tmpx, tmpy).sv);
            //std::cout << "( " << e.position[0] << "," << e.position[1] << " )" << std::endl;
}

此代码适用于8个循环(因为生成的随机数始终相同),然后在到达中间点时崩溃并尝试更新值,抛出错误: `.a.out':双重免费或损坏(输出)错误:0x0000000000d47030 *** 中止(核心倾倒) 我不知道为什么这不起作用,我无法在那里找到任何流氓指针。此外,它适用于所有其他算法,唯一的变化实际上是结构中的一个值(sv)。

我让valgrind遍历代码进行调试,但我无法指出问题。

==10260== Invalid read of size 4
==10260==    at 0x4030C0: main (in /home/alex/ClionProjects/Blatt3/a.out)
==10260==  Address 0x5a1d044 is 0 bytes after a block of size 4 alloc'd
==10260==    at 0x4C2B0E0: operator new(unsigned long) 
(in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10260==    
by 0x4081DF: __gnu_cxx::new_allocator<float>::allocate(unsigned long,void const*) 
(in /home/alex/ClionProjects/Blatt3/a.out)
==10260==    by 0x407886: std::_Vector_base<float, 
std::allocator<float>>::_M_allocate(unsigned long) (in /home/alex/ClionProjects/Blatt3 /a.out)
==10260==    by 0x4069C2: std::_Vector_base<float, std::allocator<float> >::_M_create_storage(unsigned long) (in /home/alex/ClionProjects/Blatt3/a.out)
==10260==    by 0x40539C: std::_Vector_base<float, std::allocator<float> >::_Vector_base(unsigned long, std::allocator<float> const&) (in /home/alex/ClionProjects/Blatt3/a.out)
==10260==    by 0x404045: std::vector<float, std::allocator<float> >::vector(unsigned long, std::allocator<float> const&) (in /home/alex/ClionProjects/Blatt3/a.out)
==10260==    by 0x4028AB: main (in /home/alex/ClionProjects/Blatt3/a.out)
==10260== 
==10260== 
==10260== HEAP SUMMARY:
==10260==     in use at exit: 0 bytes in 0 blocks
==10260==   total heap usage: 1,518 allocs, 1,518 frees, 41,468 bytes allocated

我感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

发布OP作为答案。

我们没有看到所有代码,这使我们很难(如果不是不可能)为您提供直接的解决方案。

在这种情况下,我首先使用-g进行编译(假设您正在使用gcc进行编译),或者valgrind无法告诉您确切的行,并且它肯定更难处理跟踪问题回到原因。在gdb中运行可执行文件也会有所帮助:当内存损坏发生时执行将停止,在大多数情况下,您可以获得堆栈跟踪。