我的代码中有关于CLI / C ++中的字符串的小内存泄漏。我试图通过删除我的unsigned char数组来修复泄漏,但是当我这样做时,我得到了一个内存访问冲突。
我认为这是因为System :: String是一个ref类型,因此,内存在下面的代码中与'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;
};
答案 0 :(得分:1)
好的,首先你的MgdStringToUChar函数存在一些问题。 wcstombs_s的第一个参数应该是指向实际size_t的指针,而不是指向null的指针。如果你想确保ch被终止,那么你也应该使用_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中的数据做了什么。没有看到全貌,很难看出这里发生了什么。