使用' new'在C ++中动态分配内存?

时间:2011-06-09 05:16:45

标签: c++ memory-management new-operator

我正在处理一些C ++代码,并且遇到了下面介绍的函数的一些问题。我之前没有使用太多的C ++,至少在很长一段时间内都没用过,所以我试着学习,因为我在很大程度上都是这样。 win32api对混淆因素没有多大帮助......

该函数成功调用两次,之后在应用程序中调用它时稍后调用失败。

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 = new char[nDn];行上失败,最后一个标记显示为'标记A'。我在指针上使用delete[]进一步无效。我知道nDn是一个值,因为我使用_itow_s将其打印到消息日志中进行调试。我也知道dnPtrstr是PTSTR。

我尝试在旧C风格中使用mallocfree(),但这并没有改善。

3 个答案:

答案 0 :(得分:2)

我试着稍微清理你的代码。 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
}

这可能无法解决您的问题,但它已消除了大量潜在错误。 鉴于我无法从您提供的代码中重现您的问题,这是我能做的最好的。

现在,如果您能够提出合理的名称而不是dnPtstrdn,那么它实际上可能几乎是可读的。 ;)

答案 1 :(得分:1)

我认为你的问题就在这一行:

wcstombs_s(pnNumCharConverted,dn,nDn+1,dnPtstr,nDn+1);

因为你告诉wcstombs_s将最多nDn + 1个字符复制到dn中,只有nDn个字符长。

尝试将行更改为:

wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,nDn);

或者可能更好:

wcstombs_s(pnNumCharConverted,dn,nDn,dnPtstr,_TRUNCATE);

我不确定你是如何调试这个或如何实现AddToMessageLog,但如果你只是检查日志以跟踪代码,并且AddToMessageLog正在缓冲你的日志记录,那么可能在刷新缓冲区之前发生错误。

答案 2 :(得分:0)

如果您确定“char * dn = new char [nDn];”失败了,TRY“set_new_handler” - &gt; http://msdn.microsoft.com/en-us/library/5fath9te(VS.80).aspx

旁注,很少:

  1. 第一个操作“size_t nDn = wcslen(dnPtstr);”不是100%正确。 你在dnPtstr上做wcslen,假设dnPtstr是unicode。但是,情况并非如此,因为根据是否定义了UNICODE,它可能是PWSTR或PSTR。因此,请使用_tcslen()。如果你花一点时间来理解UNICODE,NON-UNICODE的东西会更好,因为它们可以在Windows C ++开发中帮助你很多。
  2. 如果你只在这个函数中使用这些变量,我为什么要使用这么多“new”(我假设它)。 首选堆栈上的局部变量unles你有明确的要求。