2015-01-09 2 views
0

Я реализовал алгоритм обучения подкрепления Актер Критик с выбором действия softmax. Мое состояние - это сетка размером xmax x ymax с целью посередине. я реализовал его как вектор элементов структуры:C++ - Двойная свобода или коррупция - Я не могу найти причину

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

, что каждая точка сетки имеет значение для всех ходов (вверх, вниз, вправо, влево) и государственного значения для актера критика. Для того, чтобы получить доступ к ним, я использую:

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 ': двойная свобода или повреждение (out): 0x0000000000d47030 ** * Aborted (core dumped) Я не знаю, почему это не работает, я не могу найти ни одного изгоев указатели там. Более того, он работал для всех других алгоритмов, единственное изменение - это еще одно значение (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 

Я благодарен за любую помощь.

+0

Мы не видим весь код, так или иначе, я бы начал с компиляции с -g, иначе valgrind не говорит вам о линии, и это определенно сложнее. Поскольку он сбой, было бы лучше скомпилировать с -g, запустить исполняемый файл в gdb и получить обратную трассировку, когда он выйдет из строя. – gd1

+1

Спасибо, после того, как я перекомпилировал его, я нашел проблемную строку в верхней части кода, и теперь она работает , Возможно, опубликуйте свой комментарий в качестве ответа, чтобы я мог его проголосовать. – AlexConfused

+0

Добро пожаловать. Я отправил свой ответ. – gd1

ответ

1

Публикация в качестве ответа, предложенного ОП.

Мы не видим весь код, и это затрудняет (если не невозможно) предоставление вам прямого решения.

В этой ситуации, я бы начать с составления с -g (если вы компилируете с gcc), или valgrind не могу сказать вам точные линии, и это, безусловно, сложнее отследить проблему обратно в ее причины. Было бы также полезно запустить исполняемый файл в gdb: выполнение прекратится, когда произойдет повреждение памяти, и в большинстве случаев вы можете получить трассировку стека.

Смежные вопросы