使用';新';在C+中动态分配内存+;? 我正在研究一些C++代码,并且在下面描述的函数中存在一些问题。我以前没有使用过很多C++,至少在很长一段时间内都没有用过,所以我试着在很大程度上学习。win32api对混淆因素也没有多大帮助
函数成功调用两次,之后在应用程序中调用时失败使用';新';在C+中动态分配内存+;? 我正在研究一些C++代码,并且在下面描述的函数中存在一些问题。我以前没有使用过很多C++,至少在很长一段时间内都没有用过,所以我试着在很大程度上学习。win32api对混淆因素也没有多大帮助,c++,memory-management,new-operator,C++,Memory Management,New Operator,函数成功调用两次,之后在应用程序中调用时失败 PTSTR getDomainFromDN(PTSTR dnPtstr) { size_t nDn=wcslen(dnPtstr); size_t *pnNumCharConverted = new size_t; wchar_t *szTemp = new wchar_t[10]; // for debugging purposes _itow_s((int)nDn,szTemp,10,10); //
PTSTR getDomainFromDN(PTSTR dnPtstr) {
size_t nDn=wcslen(dnPtstr);
size_t *pnNumCharConverted = new size_t;
wchar_t *szTemp = new wchar_t[10]; // for debugging purposes
_itow_s((int)nDn,szTemp,10,10); // for debugging purposes
AddToMessageLog(EVENTLOG_ERROR_TYPE,szTemp); // for debugging purposes (displays an integer value before failing)
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker A")); // for debugging purposes
char *dn = new char[nDn];
// !!!!!!!!!!!! all goes wrong here, doesn't get to next line, nDn does have a value when it fails (61)
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker B")); // for debugging purposes
wcstombs_s(pnNumCharConverted,dn,nDn+1,dnPtstr,nDn+1);
...more code here...
delete[] dn;
delete pnNumCharConverted;
return result
}
起初我认为这是内存分配问题,因为它在char*dn=newchar[nDn]行失败代码>,最后一个标记显示为“标记A”。我在向下的指针上使用了delete[]
,但没有用。我知道nDn
是一个值,因为我使用\u itow\u s
将其打印到消息日志中进行调试。我还知道dnPtrstr
是一个PTSTR
我尝试在旧的C风格中使用malloc
以及free()
,但这并没有改善情况。我认为您的问题在于这一行:
wcstombs_s(pnnumchard,dn,nDn+1,dnPtstr,nDn+1)代码>
因为您告诉wcstombs_s将多达nDn+1个字符复制到只有nDn个字符长的dn中
尝试将行更改为:
wcstombs_s(pnnumchard,dn,nDn,dnPtstr,nDn)代码>
或者更好:
wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,_TRUNCATE)代码>
我不确定您是如何调试这个或AddToMessageLog是如何实现的,但是如果您只是检查日志以跟踪代码,并且AddToMessageLog正在缓冲您的日志记录,那么可能在刷新该缓冲区之前发生错误。我想您的问题是这一行:
wcstombs_s(pnnumchard,dn,nDn+1,dnPtstr,nDn+1)代码>
因为您告诉wcstombs_s将多达nDn+1个字符复制到只有nDn个字符长的dn中
尝试将行更改为:
wcstombs_s(pnnumchard,dn,nDn,dnPtstr,nDn)代码>
或者更好:
wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,_TRUNCATE)代码>
我不知道你是如何调试这个或者AddToMessageLog是如何实现的,但是如果你只是检查日志来跟踪代码,并且AddToMessageLog正在缓冲你的日志记录,那么可能在刷新缓冲区之前发生错误。如果你确定“char*dn=new char[nDn];”失败,请尝试“set\u new\u handler”->
另一方面,有几件事:
第一个操作“size_t nDn=wcslen(dnPtstr);”不是100%正确的假设dnPtstr为unicode,则在dnPtstr上执行wcslen。但是,情况并非如此,因为它可以是PWSTR或PSTR,取决于是否定义了UNICODE。因此,请使用_tcslen()。如果你花一些时间了解Unicode、非Unicode的东西,这将更好,因为它们在Windows C++开发中会有很大帮助。
如果只在这个函数中使用这些变量(我假设是这样),为什么要使用这么多“new”除非您有明确的要求,否则对于局部变量,首选堆栈而非堆。
如果确定“char*dn=new char[nDn];”失败,请尝试“set_new_handler”->
另一方面,有几件事:
第一个操作“size_t nDn=wcslen(dnPtstr);”不是100%正确的假设dnPtstr为unicode,则在dnPtstr上执行wcslen。但是,情况并非如此,因为它可以是PWSTR或PSTR,取决于是否定义了UNICODE。因此,请使用_tcslen()。如果你花一些时间了解Unicode、非Unicode的东西,这将更好,因为它们在Windows C++开发中会有很大帮助。
如果只在这个函数中使用这些变量(我假设是这样),为什么要使用这么多“new”除非您有明确的要求,否则对于局部变量,首选堆栈而非堆。
我试过清理一下你的代码。C++的一个大诀窍是当它可以避免时,不显式地使用内存管理。使用向量而不是原始数组。字符串而不是字符指针
不要不必要地动态分配对象。将它们放在堆栈上,在那里它们会自动释放
和其他语言一样,初始化变量
PTSTR getDomainFromDN(PTSTR dnPtstr){
std::wstring someUnknownString=dnPtstr;
大小\u t numCharConverted=0;
std::wstring temp;//用于调试目的
std::ostringstream sstr;
SSTR < P>我尝试过对代码进行消毒。对C++的一个大诀窍是在避免时,不明确使用内存管理。使用向量代替原始数组。
不要不必要地动态分配对象,把它们放在堆栈上,在那里它们会被自动释放
和其他语言一样,初始化变量
PTSTR getDomainFromDN(PTSTR dnPtstr){
std::wstring someUnknownString=dnPtstr;
大小\u t numCharConverted=0;
std::wstring temp;//用于调试目的
std::ostringstream sstr;
SSTR一旦你开始摆弄指针,比如“代码> > siZe*tpNUnCurCurrase=新SiZeTt; O.My。你使用的代码太多< <新代码> >。你的RAM内存和HDD都是满的吗?不要说我最喜欢的语言有一个旧的风格!):@ USE723 499:在C++中,你可以在堆栈上定义局部变量。size\u t*pnNumCharConverted=new size\u t;
,只需编写size\u t numCharConverted
,然后使用它。顺便说一句,您可能想看看《加速C++》一书凯尼格和MOO。当你开始摆弄指针,比如“代码”> SsieZyt*PnNuthCurrase=新的SigZet; O.My。你使用的代码太多< < <代码> >。你的RAM内存和硬盘都是满的吗?不要说我最喜欢的语言有一个旧的风格!):@ USE723 499:在C++中
PTSTR getDomainFromDN(PTSTR dnPtstr) {
std::wstring someUnknownString = dnPtstr;
size_t numCharConverted = 0;
std::wstring temp; // for debugging purposes
std::ostringstream sstr;
sstr << temp;
AddToMessageLog(EVENTLOG_ERROR_TYPE,sstr.str().c_str()); // for debugging purposes (displays an integer value before failing)
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker A")); // for debugging purposes
std::vector<char> dn(someUnknownString.size());
AddToMessageLog(EVENTLOG_ERROR_TYPE,TEXT("Marker B")); // for debugging purposes
wcstombs_s(&numCharConverted, &dn[0], dn.size(), someUnknownString.c_str(), dn.size());
...more code here...
return result
}