SIGSEGV 通过写入局部变量
SIGSEGV through writing to local variable
我目前在我的 C++ 项目中遇到了最奇怪的行为。我想做的是计算两个双向量之间的欧氏距离(嗯,实际上,双向量的向量,因此 m_Data[0].size()).
这是来源:
double NEAT::Behavior::Distance_To(NEAT::PhenotypeBehavior* other)
{
double sum = 0.0;
for (int i = 0; i < m_Data[0].size() && i < other->m_Data[0].size(); i++) {
double x1 = m_Data[0][i];
double x2 = b->m_Data[0][i];
double difference = x1 - x2;
difference *= difference;
sum += difference;
}
return sqrt(sum);
}
我最初将所有这些写在一行中,但我将其分开以找出错误。发生的事情是,在调用此函数几千次后,它会在 for 循环的最后一行抛出一个 SIGSEGV:
sum += difference;
我不知道这怎么会发生。我已经检查了堆栈跟踪,它来自 Distance_To(...) 函数并且它被精确地抛出到这一行。一旦我将其注释掉,一切都很好(但当然该功能将无法正常工作,哈哈)。每次我 运行 程序与相同的对象交互时,信号都会同时抛出。
非常感谢您的帮助。谢谢!
编辑:我已经通过在进入循环之前打印出所需的值来验证此方法中指针的完整性。所有值都正确打印。这是我用于调试目的的函数的完整版本:
double NEAT::Behavior::Distance_To(NEAT::PhenotypeBehavior* other)
{
double sum = 0.0;
Behavior* b = (Behavior*) other;
// Gets executed without any problems
if (genomeid == 300 && b->genomeid == 399) {
std::cout << "PROBLEM CASE" << std::endl;
std::cout << "Printing values for 300..." << std::endl;
for (int i = 0; i < m_Data[0].size(); i++) std::cout << m_Data[0][i] << std::endl;
std::cout << "Printing values for 399..." << std::endl;
for (int i = 0; i < m_Data[0].size(); i++) std::cout << b->m_Data[0][i] << std::endl;
}
// Doesn't get executed
if (m_Data[0].size() != other->m_Data[0].size()) {
std::cout << "Different sizes, " << m_Data[0].size() << " and " << b->m_Data[0].size() << std::endl;
}
// SIGSEGV at size() call
for (int i = 0; i < m_Data[0].size() && i < b->m_Data[0].size(); i++) {
double x1 = m_Data[0][i];
double x2 = b->m_Data[0][i];
double difference = x1 - x2;
difference *= difference;
// If this line gets commented out, no SIGSEGV but the program starts behaving weirdly afterwards (suddenly different sizes after the faulty run)
sum += difference;
}
return sqrt(sum);
}
我目前在我的 C++ 项目中遇到了最奇怪的行为。我想做的是计算两个双向量之间的欧氏距离(嗯,实际上,双向量的向量,因此 m_Data[0].size()).
这是来源:
double NEAT::Behavior::Distance_To(NEAT::PhenotypeBehavior* other)
{
double sum = 0.0;
for (int i = 0; i < m_Data[0].size() && i < other->m_Data[0].size(); i++) {
double x1 = m_Data[0][i];
double x2 = b->m_Data[0][i];
double difference = x1 - x2;
difference *= difference;
sum += difference;
}
return sqrt(sum);
}
我最初将所有这些写在一行中,但我将其分开以找出错误。发生的事情是,在调用此函数几千次后,它会在 for 循环的最后一行抛出一个 SIGSEGV:
sum += difference;
我不知道这怎么会发生。我已经检查了堆栈跟踪,它来自 Distance_To(...) 函数并且它被精确地抛出到这一行。一旦我将其注释掉,一切都很好(但当然该功能将无法正常工作,哈哈)。每次我 运行 程序与相同的对象交互时,信号都会同时抛出。
非常感谢您的帮助。谢谢!
编辑:我已经通过在进入循环之前打印出所需的值来验证此方法中指针的完整性。所有值都正确打印。这是我用于调试目的的函数的完整版本:
double NEAT::Behavior::Distance_To(NEAT::PhenotypeBehavior* other)
{
double sum = 0.0;
Behavior* b = (Behavior*) other;
// Gets executed without any problems
if (genomeid == 300 && b->genomeid == 399) {
std::cout << "PROBLEM CASE" << std::endl;
std::cout << "Printing values for 300..." << std::endl;
for (int i = 0; i < m_Data[0].size(); i++) std::cout << m_Data[0][i] << std::endl;
std::cout << "Printing values for 399..." << std::endl;
for (int i = 0; i < m_Data[0].size(); i++) std::cout << b->m_Data[0][i] << std::endl;
}
// Doesn't get executed
if (m_Data[0].size() != other->m_Data[0].size()) {
std::cout << "Different sizes, " << m_Data[0].size() << " and " << b->m_Data[0].size() << std::endl;
}
// SIGSEGV at size() call
for (int i = 0; i < m_Data[0].size() && i < b->m_Data[0].size(); i++) {
double x1 = m_Data[0][i];
double x2 = b->m_Data[0][i];
double difference = x1 - x2;
difference *= difference;
// If this line gets commented out, no SIGSEGV but the program starts behaving weirdly afterwards (suddenly different sizes after the faulty run)
sum += difference;
}
return sqrt(sum);
}