Project Chrono新手运行首个教程遇内存访问违例异常求助
Project Chrono教程代码退出时触发内存访问异常
问题描述
作为Project Chrono初学者,已配置好所有依赖模块、库及DLL,无依赖错误,但运行首个教程代码时,在即将执行到return 0前触发内存访问异常,怀疑是shared_ptr被重复释放导致。
教程代码
#include "chrono/physics/ChLinkMotorRotationSpeed.h" #include "chrono/physics/ChSystemNSC.h" using namespace chrono; int main(int argc, char* argv[]) { GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n"; { // // EXAMPLE 1: // GetLog() << " Example: create a physical system.. \n"; // The physical system: it contains all physical objects. ChSystemNSC sys; // Create a bunch of rigid bodies.. // Note that we use shared pointers, so you don't // have to care about the deletion (never use delete.. for // objects managed with shared pointers! it will be automatic!) auto my_body_A = chrono_types::make_shared<ChBody>(); auto my_body_B = chrono_types::make_shared<ChBody>(); auto my_body_C = chrono_types::make_shared<ChBody>(); // Create some markers.. // Markers are 'auxiliary coordinate systems' to be added // to rigid bodies. // Again, note that they are managed by shared pointers. auto my_marker_a1 = chrono_types::make_shared<ChMarker>(); auto my_marker_a2 = chrono_types::make_shared<ChMarker>(); auto my_marker_b1 = chrono_types::make_shared<ChMarker>(); auto my_marker_b2 = chrono_types::make_shared<ChMarker>(); // You can create some forces too... auto my_force_a1 = chrono_types::make_shared<ChForce>(); auto my_force_a2 = chrono_types::make_shared<ChForce>(); // Here you will add forces and markers to rigid // bodies. // Note: the same marker shouldn't be added to multiple bodies. my_body_A->AddMarker(my_marker_a1); my_body_A->AddMarker(my_marker_a2); my_body_A->AddForce(my_force_a1); my_body_A->AddForce(my_force_a2); my_body_B->AddMarker(my_marker_b1); my_body_B->AddMarker(my_marker_b2); // Ok, remember that rigid bodies must be added to // the physical system. sys.AddBody(my_body_A); sys.AddBody(my_body_B); sys.AddBody(my_body_C); // Show the hierarchy in the shell window... GetLog() << "Here's the system hierarchy which you built: \n\n "; sys.ShowHierarchy(GetLog()); // Do you want to remove items? Use the // Remove...() functions. my_body_A->RemoveAllForces(); // Remove a single body.. sys.RemoveBody(my_body_A); // Add markers to another body... my_body_B->AddMarker(my_marker_a1); my_body_B->AddMarker(my_marker_a2); my_body_B->AddForce(my_force_a1); my_body_B->AddForce(my_force_a2); // By the way, you can set an Ascii name for objects as desired: my_marker_a1->SetName("JohnFoo"); // ..so you can later use my_body_B.SearchMarker("JohnFoo"); etc. GetLog() << "\n\n\nHere's the system hierarchy after modifications: \n\n "; sys.ShowHierarchy(GetLog()); } return 0; }
异常信息
在ConsoleApplication7.exe中,于0x00007FFF6E0ECA3E地址(ChronoEngine.dll)处抛出异常:0xC0000005:写入位置0x00000185243FCA0F时发生访问违规
触发异常的代码片段
异常触发于memory文件中的以下代码:
void _Destroy() noexcept override { // destroy managed resource delete _Ptr; }
问题原因及修复方案
原因分析
问题出在未先从原刚体移除marker/force,就直接将其添加到另一个刚体:
- 执行
sys.RemoveBody(my_body_A)时,my_body_A被销毁,其内部持有的marker和force对象会被处理(Chrono内部可能存在裸指针操作或自定义内存逻辑,直接释放了部分资源)。 - 后续将同一marker/force添加到
my_body_B,导致my_body_B持有指向已释放内存的无效指针,程序退出时触发重复释放的访问违规。
修复步骤
严格遵循教程注释中“同一marker不能添加到多个刚体”的规则,在转移对象前先从原刚体移除:
// 在移除my_body_A前,先移除其持有的marker和force my_body_A->RemoveMarker(my_marker_a1); my_body_A->RemoveMarker(my_marker_a2); my_body_A->RemoveForce(my_force_a1); my_body_A->RemoveForce(my_force_a2); sys.RemoveBody(my_body_A); // 再将marker和force添加到my_body_B my_body_B->AddMarker(my_marker_a1); my_body_B->AddMarker(my_marker_a2); my_body_B->AddForce(my_force_a1); my_body_B->AddForce(my_force_a2);
或者更简单的方式:直接为my_body_B创建新的marker和force实例,避免重复使用同一对象。
内容的提问来源于stack exchange,提问作者Frank ly
相关产品推荐
相关产品推荐

