You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,就直接将其添加到另一个刚体:

  1. 执行sys.RemoveBody(my_body_A)时,my_body_A被销毁,其内部持有的marker和force对象会被处理(Chrono内部可能存在裸指针操作或自定义内存逻辑,直接释放了部分资源)。
  2. 后续将同一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 12:52:36