使用“新”在C++中动态分配内存?

发布于 2024-11-14 18:15:36 字数 1286 浏览 5 评论 0原文

我正在编写一些 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 风格中使用 malloc 以及 free() ,但这并没有改善情况。

I am working on some C++ code and am having some problems with the function described below. I haven't used much C++ before, at least not for a long time and so i'm trying to learn as I go along to a large extent. The win32api doesn't help much with the confusion factor either...

The function is succesfully called twice, before failing when called at a later stage when it is called in the application.

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
}

At first i thought it was a memory allocation problem or something as it fails on the line char *dn = new char[nDn];, the last marker showing as 'Marker A'. I used delete[] on the pointer further down to no avail. I know that nDn is a value because I print this out to a message log using _itow_s for debugging. I also know that dnPtrstr is a PTSTR.

I tried using malloc as well with free() in the old C style but this doesn't improve things.

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

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

发布评论

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

评论(3

无边思念无边月 2024-11-21 18:15:36

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

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

现在,如果您能想出合理的名称而不是 dnPtstr 和 dn,它实际上可能几乎是可读的。 ;)

I tried sanitizing your code a bit. One of the big tricks to C++ is to not explicitly use memory management when it can be avoided. Use vectors instead of raw arrays. Strings instead of char pointers.

And don't unnecessarily allocate objects dynamically. Put them on the stack, where they're automatically freed.

And, as in every other language, initialize your variables.

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
}

This might not have solved your problem, but it has eliminated a large number of potential errors.
Given that I can't reproduce your problem from the code you've supplied, this is really the best I can do.

Now, if you could come up with sane names instead of dnPtstr and dn, it might actually be nearly readable. ;)

深海少女心 2024-11-21 18:15:36

我认为你的问题是这一行:

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 正在缓冲您的日志记录,那么可能在刷新该缓冲区之前发生错误。

i think your problem is this line:

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

because you are telling wcstombs_s to copy up to nDn+1 characters into dn which is only nDn characters long.

try changing the line to:

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

or perhaps better yet:

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

im not sure how you are debugging this or how AddToMessageLog is implemented, but if you are just inspecting the log to trace the code, and AddToMessageLog is buffering your logging, then perhaps the error occurs before that buffer is flushed.

云朵有点甜 2024-11-21 18:15:36

如果您确定“char *dn = new char[nDn];”失败,尝试“set_new_handler”-> 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. 如果您只在这个函数中使用这些变量(我假设是这样),为什么要使用这么多“新”变量呢? 对于局部变量,优先选择堆栈而不是堆,除非您有明确的要求。

If you are sure that "char *dn = new char[nDn];" is failing, TRY "set_new_handler" -> http://msdn.microsoft.com/en-us/library/5fath9te(VS.80).aspx

On a side note, few things:

  1. The very first operation "size_t nDn=wcslen(dnPtstr);" is not 100% correct. You are doing wcslen on dnPtstr assuming dnPtstr to be unicode. However, this is not the case since it could be PWSTR or PSTR based on whether UNICODE is defined or not. So, use _tcslen(). Its better if you give some time to understand UNICODE, NON-UNICODE stuff since they would help you a lot in Windows C++ development.
  2. Why are you using so many "new" if you are using these variables only in this function (I am assuming it). Prefer stack over heap for local variables unles you have a definite requirement.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文