由于某种原因,此代码在运行时导致堆栈溢出异常:
neuralnetwork::CPerceptron::inputEvent(const neuralnetwork::IConnection * origin, double value)
std::map<std::reference_wrapper<const IConnection>, float64_t, _CPerceptronComparator>::iterator it = m_inputValues.find( std::ref( *origin ) );
if ( it == m_inputValues.end() )
{
throw "Some error";
}
...
}
_CPerceptronComparator看起来像这样(需要它,因为std :: ref没有运算符&lt;):
class _CPerceptronComparator
{
public:
_CPerceptronComparator()
{
}
bool operator()( const std::reference_wrapper<const neuralnetwork::IConnection *> & val1,
const std::reference_wrapper<const neuralnetwork::IConnection *> & val2 ) const
{
return (val1.get()) < (val2.get());
}
bool operator()( const std::reference_wrapper<const neuralnetwork::IConnection> & val1,
const std::reference_wrapper<const neuralnetwork::IConnection> & val2 ) const
{
return &( val1.get() ) < &( val2.get() );
}
bool operator()( const std::reference_wrapper<neuralnetwork::IConnection> & val1,
const std::reference_wrapper<neuralnetwork::IConnection> & val2 ) const
{
return &( val1.get() ) < &( val2.get() );
}
};
我添加了更多代码,所以也许你可以提供帮助。这就是我添加输入连接的方式:
void CPerceptron::addInputConnection( IConnection * inConn )
{
m_outConnections.insert( std::ref(*inConn) );
m_inputValues.insert( std::pair<std::reference_wrapper<IConnection>, float64_t>( std::ref( *inConn ), 0.0f ) );
m_isInputReady.insert( std::pair<std::reference_wrapper<IConnection>, bool>( std::ref( *inConn ), false ) );
}
注意:我知道std :: make_pair更容易使用,但我更换了它,希望它能引起我的问题。你知道,它不可能看到它返回的那种类型。这个解决方案可能更难阅读,但是很简单。
错误:神经网络中0x002C2EC9处的未处理异常:0xC00000FD:堆栈溢出(参数:0x00000001,0x00102FFC)。
调用堆栈:
Neural Network.exe!std::_Iterator_base12::_Orphan_me() Line 192 C++
Neural Network.exe!std::_Iterator_base12::_Adopt(const std::_Container_base12 * _Parent) Line 165 C++
Neural Network.exe!std::_Iterator_base12::operator=(const std::_Iterator_base12 & _Right) Line 129 C++
Neural Network.exe!std::_Iterator_base12::_Iterator_base12(const std::_Iterator_base12 & _Right) Line 121 C++
Neural Network.exe!std::_Iterator012<std::bidirectional_iterator_tag,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double>,int,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> const *,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> const &,std::_Iterator_base12>::_Iterator012<std::bidirectional_iterator_tag,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double>,int,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> const *,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> const &,std::_Iterator_base12>(const std::_Iterator012<std::bidirectional_iterator_tag,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double>,int,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> const *,std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> const &,std::_Iterator_base12> & __that) C++
Neural Network.exe!std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > >,std::_Iterator_base12>::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > >,std::_Iterator_base12>(const std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > >,std::_Iterator_base12> & __that) C++
Neural Network.exe!std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > > >::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > > >(const std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > > > & __that) C++
Neural Network.exe!std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > > >::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > > >(const std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> > > > & __that) C++
Neural Network.exe!std::_Tree<std::_Tmap_traits<std::reference_wrapper<neuralnetwork::IConnection const >,double,neuralnetwork::_CPerceptronComparator,std::allocator<std::pair<std::reference_wrapper<neuralnetwork::IConnection const > const ,double> >,0> >::find(const std::reference_wrapper<neuralnetwork::IConnection const > & _Keyval) Line 1553 C++
Neural Network.exe!neuralnetwork::CPerceptron::inputEvent(const neuralnetwork::IConnection * origin, double value) Line 94 C++
让我注意一下,如果我调试地图,它应该包含一个元素。 (或者至少它的大小告诉我它有1个元素。)
我用什么类型的迭代来迭代地图并不重要,它会在第一个查询中产生错误。我使用的是Visual Studio 2013。
我现在真的很无助。
抱歉格式不正确。
答案 0 :(得分:1)
问题是由无限循环引起的(实际上我曾经见过堆栈溢出的唯一原因)。
void CPerceptron::addInputConnection( IConnection * inConn )
{
m_outConnections.insert( std::ref(*inConn) );
m_inputValues.insert( std::pair<std::reference_wrapper<IConnection>, float64_t>( std::ref( *inConn ), 0.0f ) );
m_isInputReady.insert( std::pair<std::reference_wrapper<IConnection>, bool>( std::ref( *inConn ), false ) );
}
我在一个名为addInputConnection的函数中插入m_outConnections,它在图形中创建了一个圆(在神经网络中),因此传播结果导致无限循环(传播函数不在帖子中)。
这是一个很好的例子,很容易错过这么小的东西,但其他无用的帖子。将其删除IMO。
答案 1 :(得分:0)
我已经拿走了你的代码并创建了一个我可以编译和运行的模型。如果在gcc下无法编译4.8.1无法进行模板替换。在预感中这与使用引用包装器(以及您使用不同的编译器和标准库)有关,我定义了一个运算符&lt;对于类IConnection并删除了包装器和_CPerceptronComparator。它已编译,似乎正在运行。
您可以看到code in coliru here。
#include <iostream>
#include <map>
#include <stdexcept>
typedef double float64_t;
namespace neuralnetwork {
class IConnection {
float64_t _value = 0.0;
public:
IConnection( float64_t v ) : _value(v) {}
float64_t get() const { return _value; }
friend inline bool operator< ( const IConnection & lhs, const IConnection & rhs ) { return lhs.get() < rhs.get(); }
};
class CPerceptron {
std::map<const IConnection, float64_t>
m_inputValues, m_isInputReady;
public:
void inputEvent(const neuralnetwork::IConnection * origin, double value);
void addInputConnection( IConnection * inConn );
};
void CPerceptron::addInputConnection( IConnection * inConn )
{
m_inputValues.insert( std::pair<IConnection, float64_t>( *inConn, 0.0f ) );
}
} // namespace neuralnetwork
void neuralnetwork::CPerceptron::inputEvent(const neuralnetwork::IConnection * origin, double value)
{
std::map< const neuralnetwork::IConnection, float64_t >::iterator
it = m_inputValues.find( *origin );
if ( it == m_inputValues.end() )
{
throw std::runtime_error("Some error");
}
// ...
}
int main( int argc, char *argv[] )
{
neuralnetwork::IConnection ic( 1.0 );
neuralnetwork::CPerceptron cp;
cp.addInputConnection( & ic );
cp.inputEvent( & ic, 2.0 );
std::cout << "No stack overflow here!" << std::endl;
return 0;
}
这是我得到的输出
g++-4.8 -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
No stack overflow here!
<强>更新强>:
根据OP的观察,我创建了两个版本,它们使用对象的地址在地图中排序:
在堆栈上创建的对象(失败):
http://coliru.stacked-crooked.com/a/02d1f262a75b1d25
在堆上创建的对象(失败):
http://coliru.stacked-crooked.com/a/728cf77040143f21
STL将有序映射实现为二叉树,它使用复制构造函数将对象复制到映射(二叉树)。它使用你提供的比较器(或运算符&lt;)来确定插入它的位置(以及后来弄清楚如何找到它),但是因为你正在使用对象的地址来对它进行排序,并且当它被获取时会发生变化复制 - 问题!
使用std :: shared_ptr工作(添加了一个间接级别)。他们说计算机科学中的任何问题都可以通过一个间接层面来解决 - 似乎在这里工作。
http://coliru.stacked-crooked.com/a/6aa631675133289b
更新2:
更简单,摆脱get()
函数并使用指向对象的指针作为地图中的关键字,直接比较指针的值小于operator<
: