在 CLI 中处理 String^ ?

发布于 2024-07-30 12:31:22 字数 1145 浏览 2 评论 0原文

我的代码中有一个关于 CLI/C++ 中字符串的小内存泄漏。 我尝试通过删除 unsigned char 数组来修复泄漏,但是当我这样做时,我遇到了内存访问冲突。

我认为这是因为 System::String 是引用类型,因此,内存与下面代码中的“testString”和“uch”相关联。 那是对的吗? 如果是这样,我如何分离内存,以便释放内存并仍然返回 System::String?

myStatus get_testString(String^% testString)
{
    uchar* uch = 0;
    bool b = MgdStringToUChar(testString, uch);
    myStatus s = m_NativeMsg->get_testString(uch);
    testString = (reinterpret_cast<const char*>(uch));

    delete []uch;//this line causes an error       
    uch=0; 
    return s;
}

static bool MgdStringToUChar(System::String^ s, uchar*& uch)
{
    pin_ptr<const wchar_t> wch = PtrToStringChars( s ); 
    int len = (( s->Length+1) * 2); 
    size_t * st = 0; 
    char *ch = new char[ len ]; 
    bool result = wcstombs_s(st,ch, len, wch, len ) != -1; 
    if(!result) 
        throw (gcnew Exception("Could not parse string in :: MgdStringToUChar")); 
    uch = new uchar[len]; 
    int i=0; 
    while(i<len+1) 
    { 
        uch[i] = ch[i]; 
        i++; 
    } 
    delete st; 
    st=0; 
    delete [] ch; 
    ch=0; 
    return true; 
}; 

I have a small memory leak in my code regarding Strings in CLI/C++. I've tried to fix the leak by deleting my unsigned char array, but when I do, I get a Memory Access Violation.

I assume this is because the System::String is a ref type, and because of that, the memory is associated with both 'testString' and 'uch' in the code below. Is that correct? If so, how can I separate the memory so that I can free up the memory and still return a System::String?

myStatus get_testString(String^% testString)
{
    uchar* uch = 0;
    bool b = MgdStringToUChar(testString, uch);
    myStatus s = m_NativeMsg->get_testString(uch);
    testString = (reinterpret_cast<const char*>(uch));

    delete []uch;//this line causes an error       
    uch=0; 
    return s;
}

static bool MgdStringToUChar(System::String^ s, uchar*& uch)
{
    pin_ptr<const wchar_t> wch = PtrToStringChars( s ); 
    int len = (( s->Length+1) * 2); 
    size_t * st = 0; 
    char *ch = new char[ len ]; 
    bool result = wcstombs_s(st,ch, len, wch, len ) != -1; 
    if(!result) 
        throw (gcnew Exception("Could not parse string in :: MgdStringToUChar")); 
    uch = new uchar[len]; 
    int i=0; 
    while(i<len+1) 
    { 
        uch[i] = ch[i]; 
        i++; 
    } 
    delete st; 
    st=0; 
    delete [] ch; 
    ch=0; 
    return true; 
}; 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溺孤伤于心 2024-08-06 12:31:22

好的,首先您的 MgdStringToUChar 函数有一些问题。 wcstombs_s 的第一个参数应该是指向实际 size_t 的指针,而不是指向 null 的指针。 如果您想确保 ch 以 null 终止,那么您也应该使用 _TRUNCATE 或 len-1 作为计数参数。

从 ch 缓冲区到生成的 uchar 缓冲区的复制也可能超出了缓冲区的末尾。

static bool MgdStringToUChar(System::String^ s, uchar*& uch)
{
    pin_ptr<const wchar_t> wch = PtrToStringChars( s ); 
    int len = (( s->Length+1) * 2); 
    size_t st = 0;
    char *ch = new char[ len ]; 

    bool result = wcstombs_s(&st, ch, len, wch, _TRUNCATE) != -1; 
    if(!result) 
        throw (gcnew Exception("Could not parse string in :: MgdStringToUChar")); 

    uch = new uchar[st+1]; 
    uch[st] = NULL;

    for(int i = 0; i < st; i++) 
    { 
        uch[i] = ch[i]; 
    } 

    delete [] ch; 

    return true; 
}; 

鉴于您似乎需要基本的 ANSI 转换,您也可以像这样更简单地执行此操作:

static bool MgdStringToUChar(System::String^ s, uchar*& uch)
{
    char* ch = (char*)(void*)Marshal::StringToHGlobalAnsi(str);

    size_t st = strlen(ch);
    uch = new uchar[st + 1]; 
    uch[st] = NULL;

    for(int i = 0; i < st; i++) 
    { 
        uch[i] = ch[i]; 
    } 

    Marshal::FreeHGlobal(ch);

    return true; 
}; 

这应该会更好一些。 但是我仍然担心 get_testString 对 uch 中的数据做了什么。 如果没有看到完整的图片,就很难了解这里发生了什么。

Ok, for a start your MgdStringToUChar function has some problems. The first parameter to wcstombs_s should be a pointer to a real size_t not a pointer to null. If you want to ensure that ch is null terminated then you should use _TRUNCATE or len-1 as the count parameter too.

The copy from the ch buffer to the resultant uchar buffer was also probably going over the end of the buffer.

static bool MgdStringToUChar(System::String^ s, uchar*& uch)
{
    pin_ptr<const wchar_t> wch = PtrToStringChars( s ); 
    int len = (( s->Length+1) * 2); 
    size_t st = 0;
    char *ch = new char[ len ]; 

    bool result = wcstombs_s(&st, ch, len, wch, _TRUNCATE) != -1; 
    if(!result) 
        throw (gcnew Exception("Could not parse string in :: MgdStringToUChar")); 

    uch = new uchar[st+1]; 
    uch[st] = NULL;

    for(int i = 0; i < st; i++) 
    { 
        uch[i] = ch[i]; 
    } 

    delete [] ch; 

    return true; 
}; 

You could also do this more simply like this given that you seem to need the basic ANSI conversion:

static bool MgdStringToUChar(System::String^ s, uchar*& uch)
{
    char* ch = (char*)(void*)Marshal::StringToHGlobalAnsi(str);

    size_t st = strlen(ch);
    uch = new uchar[st + 1]; 
    uch[st] = NULL;

    for(int i = 0; i < st; i++) 
    { 
        uch[i] = ch[i]; 
    } 

    Marshal::FreeHGlobal(ch);

    return true; 
}; 

This should work a bit better. However I'm still concerned about what get_testString is doing to the data in uch. Without seeing the full picture it's difficult to see what's going on here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文