使用';新';在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
    }