【问题标题】:Runtime exception in std::string delete operator when converting System::String to std::string将 System::String 转换为 std::string 时 std::string 删除运算符中的运行时异常
【发布时间】:2018-03-19 22:45:25
【问题描述】:

我正在使用带有C#C++ 代码的C++ cli 解决方案。

当我尝试将 System::String 转换为 std::string 时,每次运行都会出现以下运行时异常:

ucrtbased.dll!00007ffd9902b9b0()    Unknown
ucrtbased.dll!00007ffd9902eac5()    Unknown
MyApp.dll!operator delete(void * block) Line 21 C++
[Managed to Native Transition]  
MyApp.dll!std::_Deallocate(void* _Ptr, unsigned __int64 _Count, unsigned __int64 _Sz) Line 133  C++
MyApp.dll!std::allocator<char>::deallocate(char* _Ptr, unsigned __int64 _Count) Line 721    C++
MyApp.dll!std::_Wrap_alloc<std::allocator<char> >::deallocate(char* _Ptr, unsigned __int64 _Count) Line 988 C++
MyApp.dll!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy(bool _Built, unsigned __int64 _Newsize) Line 2260 C++
MyApp.dll!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::=(std::basic_string<char,std::char_traits<char>,std::allocator<char> >& _Right) Line 934    C++
MyApp.dll!MyApp::DoStuff(System::String^ input) Line 59 C++

或者当我在没有调试器的情况下运行时:

我的代码,我尝试了两个选项,都导致同样的崩溃:

选项 1

void MyApp::DoStuff(System::String^ input) {
    msclr::interop::marshal_context context;
    std::string converted = context.marshal_as<const char*>(LicenseOEM);
}

选项 2

std::string SystemToStd(System::String^ sys) {
    int len = sys->Length;
    char* buff = (char*)malloc((len + 1) * sizeof(char));
    for (int i = 0; i < sys->Length; i++) {
        buff[i] = sys[i];
    }
    buff[len] = '\0';
    std::string str = std::string(buff, len);
    free(buff);
    return str;
}

void MyApp::DoStuff(System::String^ input) {
    std::string converted = SystemToStd(LicenseOEM);
}

【问题讨论】:

  • 不应标记为 C++。 C++/CLI 是 ECMA-372 下的独立语言。 C++/CLI(与 C++ 相比)不幸地被命名为 JavaScript(与 Java 相比)。
  • 好吧,考虑到差异,我的堆栈有 C++ 代码,所以不能与这个标签相差那么远。

标签: c++ c++-cli clr marshalling stdstring


【解决方案1】:

也许这是一个 C++ 主题。

您是否确保为您的配置绑定正确/合适/相同的运行时 dll。

来自微软的调试 dll(其他我不知道)试图找出是否有人破坏了内存。 他们通过提供不同的新/删除实现来做到这一点。 基本上,它们扩大了分配的内存,在分配的内存之前和之后都有未使用的内存。然后他们用模式和信息填充它,并给你指向你的对象的指针。删除/释放对象时,它们会为您的内存区域获取正确的值并控制信息以及是否有人覆盖了您的对象之前和之后的模式。

所以你尝试绑定一个使用 release 作为配置编译的 dll。 但是现在您尝试找出一些东西,使用调试,然后忘记您的运行时 dll 不匹配 然后您的代码正在使用调试信息创建它,但是 您将此对象提供给本机/cpp 函数,该函数是使用 release 编译的,并尝试释放该对象,但该对象不起作用。反之亦然 release std:string 通过调试删除被释放。

实际上我用谷歌搜索了你的失败信息和一些相同方向的提示,所以你可以重新检查 Debug Assertion Failed! Expression: __acrt_first_block == header

【讨论】:

  • 确实问题是在Debug中使用了一些C++ dll而在Release中使用了其他的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多