C++ cli C++/删除[]时发生CLI堆错误

C++ cli C++/删除[]时发生CLI堆错误,c++-cli,C++ Cli,我似乎在删除char*数组时遇到问题。当调用delete[]时,它由于堆损坏而崩溃: typedef struct _CDB_SYMBOL_INFO { char * name; unsigned long address; unsigned long value; } CDB_SYMBOL_INFO; // ... for each( Symbol ^ symbol in bls->Symbols ) {

我似乎在删除
char*
数组时遇到问题。当调用
delete[]
时,它由于堆损坏而崩溃:

typedef struct _CDB_SYMBOL_INFO {
    char *          name;
    unsigned long   address;
    unsigned long   value;
} CDB_SYMBOL_INFO;

// ...

    for each( Symbol ^ symbol in bls->Symbols )
    {
        CDB_SYMBOL_INFO symbol_info;

        symbol_info.name = new char[symbol->Name->Length];
        Marshal::Copy( symbol->Name->ToCharArray(), 0, IntPtr( (char*) symbol_info.name ), symbol->Name->Length );

        // see enumerate_cdb_symbols_callback(..)
        cdb_call_back(&symbol_info, *call_back);

        delete[] symbol_info.name; // Crashes here
    }

// ...
我看不出这里有什么问题



你调用的是<代码>::复制一个16位元素数组(< net >代码>系统::char < /C> >不是C++ >代码> char < /COD>!),第四个参数是元素的数量而不是字节数,所以实际上你复制了代码>符号> >长度** 2 < /Cord>字节,这是你的缓冲区的两倍。由此产生的溢出会损坏堆元数据,导致
delete[]
崩溃

使用类型< <代码> WCHARYTT < /> >,它是匹配<代码>系统:C++ ch/<代码>的C++类型,或者将字符串转换为ASCII,可能是通过<代码> ToCARRALYAY()/<代码> >代码>编码::ASCII::GetBytes(符号-> name)< /C>。或者UTF-8,在这种情况下,您不能假定

symbol->Name->Length
是必要的缓冲区大小

更简单的方法是使用C++/CLI附带的
marshal_as
库:

#include <msclr\marshal_cppstd.h>
using namespace msclr::interop;

for each( Symbol ^ symbol in bls->Symbols )
{
    std::string sym_name = marshal_as<std::string>(symbol->Name);

    CDB_SYMBOL_INFO symbol_info;
    symbol_info.name = &sym_name[0];

    // see enumerate_cdb_symbols_callback(..)
    cdb_call_back(&symbol_info, *call_back);
}
#包括
使用名称空间msclr::interop;
对于每个(bls中的符号^Symbol->Symbol)
{
std::string sym_name=marshal_as(符号->名称);
CDB_SYMBOL_INFO SYMBOL_INFO;
symbol_info.name=&sym_name[0];
//请参阅枚举cdb符号回调(..)
cdb回拨(符号信息,*回拨);
}

它做了一些未指定的单字节字符编码(最有可能的ASCII),并使用RAII自动释放内存。

< p>您调用<代码>元帅::复制16位元素的数组< /COD>过载(.NET <代码>系统::char < /C> >不是C++ >代码> char < /代码>!)第四个参数是元素的数量,而不是字节的数量,因此您实际上是在复制
symbol->Name->Length*2
字节,这是缓冲区大小的两倍。由此产生的溢出会损坏堆元数据,导致
delete[]
崩溃

使用类型< <代码> WCHARYTT < /> >,它是匹配<代码>系统:C++ ch/<代码>的C++类型,或者将字符串转换为ASCII,可能是通过<代码> ToCARRALYAY()/<代码> >代码>编码::ASCII::GetBytes(符号-> name)< /C>。或者UTF-8,在这种情况下,您不能假定

symbol->Name->Length
是必要的缓冲区大小

更简单的方法是使用C++/CLI附带的
marshal_as
库:

#include <msclr\marshal_cppstd.h>
using namespace msclr::interop;

for each( Symbol ^ symbol in bls->Symbols )
{
    std::string sym_name = marshal_as<std::string>(symbol->Name);

    CDB_SYMBOL_INFO symbol_info;
    symbol_info.name = &sym_name[0];

    // see enumerate_cdb_symbols_callback(..)
    cdb_call_back(&symbol_info, *call_back);
}
#包括
使用名称空间msclr::interop;
对于每个(bls中的符号^Symbol->Symbol)
{
std::string sym_name=marshal_as(符号->名称);
CDB_SYMBOL_INFO SYMBOL_INFO;
symbol_info.name=&sym_name[0];
//请参阅枚举cdb符号回调(..)
cdb回拨(符号信息,*回拨);
}

它做了一些未指定的单字节字符编码(最有可能的ASCII),并使用RAII自动释放内存。

< p>您调用<代码>元帅::复制16位元素的数组< /COD>过载(.NET <代码>系统::char < /C> >不是C++ >代码> char < /代码>!)第四个参数是元素的数量,而不是字节的数量,因此您实际上是在复制
symbol->Name->Length*2
字节,这是缓冲区大小的两倍。由此产生的溢出会损坏堆元数据,导致
delete[]
崩溃

使用类型< <代码> WCHARYTT < /> >,它是匹配<代码>系统:C++ ch/<代码>的C++类型,或者将字符串转换为ASCII,可能是通过<代码> ToCARRALYAY()/<代码> >代码>编码::ASCII::GetBytes(符号-> name)< /C>。或者UTF-8,在这种情况下,您不能假定

symbol->Name->Length
是必要的缓冲区大小

更简单的方法是使用C++/CLI附带的
marshal_as
库:

#include <msclr\marshal_cppstd.h>
using namespace msclr::interop;

for each( Symbol ^ symbol in bls->Symbols )
{
    std::string sym_name = marshal_as<std::string>(symbol->Name);

    CDB_SYMBOL_INFO symbol_info;
    symbol_info.name = &sym_name[0];

    // see enumerate_cdb_symbols_callback(..)
    cdb_call_back(&symbol_info, *call_back);
}
#包括
使用名称空间msclr::interop;
对于每个(bls中的符号^Symbol->Symbol)
{
std::string sym_name=marshal_as(符号->名称);
CDB_SYMBOL_INFO SYMBOL_INFO;
symbol_info.name=&sym_name[0];
//请参阅枚举cdb符号回调(..)
cdb回拨(符号信息,*回拨);
}

它做了一些未指定的单字节字符编码(最有可能的ASCII),并使用RAII自动释放内存。

< p>您调用<代码>元帅::复制16位元素的数组< /COD>过载(.NET <代码>系统::char < /C> >不是C++ >代码> char < /代码>!)第四个参数是元素的数量,而不是字节的数量,因此您实际上是在复制
symbol->Name->Length*2
字节,这是缓冲区大小的两倍。由此产生的溢出会损坏堆元数据,导致
delete[]
崩溃

使用类型< <代码> WCHARYTT < /> >,它是匹配<代码>系统:C++ ch/<代码>的C++类型,或者将字符串转换为ASCII,可能是通过<代码> ToCARRALYAY()/<代码> >代码>编码::ASCII::GetBytes(符号-> name)< /C>。或者UTF-8,在这种情况下,您不能假定

symbol->Name->Length
是必要的缓冲区大小

更简单的方法是使用C++/CLI附带的
marshal_as
库:

#include <msclr\marshal_cppstd.h>
using namespace msclr::interop;

for each( Symbol ^ symbol in bls->Symbols )
{
    std::string sym_name = marshal_as<std::string>(symbol->Name);

    CDB_SYMBOL_INFO symbol_info;
    symbol_info.name = &sym_name[0];

    // see enumerate_cdb_symbols_callback(..)
    cdb_call_back(&symbol_info, *call_back);
}
#包括
使用名称空间msclr::interop;
对于每个(bls中的符号^Symbol->Symbol)
{
std::string sym_name=marshal_as(符号->名称);
CDB_SYMBOL_INFO SYMBOL_INFO;
symbol_info.name=&sym_name[0];
//请参阅枚举cdb符号回调(..)
cdb回拨(符号信息,*回拨);
}

它执行一些未指定的单字节字符编码(最有可能是ASCII),并使用RAII自动释放内存。

cdb\u回调的作用是什么(&symbol\u info,*回调)实际做什么?它是否提供了指向CDB_SYMBOL_INFO的不同指针,或者已经释放了它?@πάνταῥεῖ 这在目前没有任何作用。请参阅我的编辑。CDB\u符号\u信息*一点也不动。很难从您当前显示的代码中看出发生了什么。我看不见