【问题标题】:Deallocating function's A run-time memory inside function B释放函数 B 内的函数 A 运行时内存
【发布时间】:2012-09-13 11:27:45
【问题描述】:
#ifndef UNICODE
#define UNICODE
#endif

#include <iostream>
#include <Windows.h>
#include <queue>

using namespace std;

void addSomeContent(queue<TCHAR*> &s)
{
    static int counter=0;
    TCHAR* buffer = new TCHAR[250]; //Allocate memory on heap

    wsprintf(buffer,TEXT("foo%d"),counter);

    s.push(buffer);
    counter++;

    if(counter < 10)
    addSomeContent(s);

}


int main (void)
{
    queue<TCHAR*> strings; 

    addSomeContent(strings);

    while(!strings.empty()) 
    {   
        wcout<<strings.front()<<endl;
        strings.pop();
    }

    //Here I want to destroy the "buffer" from the function "addSomeContent"
    wcout<<TEXT("Memory has been cleaned!\n");

    system("pause");
    return (0);
}

如果我在函数末尾删除了宽字符数组,我就无法处理引用它的队列。现在,我的简单程序编译并运行良好,但显然在堆中保留垃圾并不被认为是一种安全的编程实践。
上次使用后如何删除“缓冲区”?

【问题讨论】:

  • queue&lt;unique_ptr&lt;TCHAR&gt;&gt; 或只是 delete[] strings.back() 在 strings.pop() 之前。你也应该使用back 而不是front
  • @SethCarnegie 从您的评论中做出回答。
  • @SethCarnegie 如果我想实现 FIFO 数据结构,为什么要返回?
  • FWIW,让操作系统处理堆释放并没有什么不安全,只要它是您生命周期设计的一部分。 (这是假设您使用的是这样的操作系统。)事实上,事后尝试添加显式解除分配通常更具破坏性只是为了最佳实践.
  • @0x6B6F77616C74 你说得对,我忘了你用的是queue,那应该是front。我把它放在一个答案中。

标签: c++ pointers memory-management stl heap-memory


【解决方案1】:

您可以使用queue&lt;unique_ptr&lt;TCHAR[]&gt;&gt; 来完全避免内存释放,或者您可以在将内存从queue 中删除之前简单地释放内存,如下所示:

delete[] strings.front();
strings.pop();

【讨论】:

  • unique_ptr 不正确,看我的回答。您希望 unique_ptr 删除 [],而不是删除。这绝对是内存泄漏。
  • @cooky451 非常感谢你,我已经修好了。此外,它不会是内存泄漏,而是未定义的行为。
【解决方案2】:

同意 Seth 关于将 unique_ptr 用于您的队列,或者您可以简单地调用

   delete[] strings.front()

在strings.pop()之前

应该使用front() 来确保我们清理即将到达的元素pop(),即队列中最旧的元素,而不是最新的back()!

【讨论】:

    【解决方案3】:

    如果您只想使用字符串,我会考虑使用

    typedef std::basic_string<TCHAR> tstring;
    std::queue<tstring> strings;
    

    否则你可以使用

    std::queue<std::unique_ptr<TCHAR[]>> strings; // notice the [], they are important!
    

    unique_ptr 是 C++11,但我认为所有主要编译器都支持它。我什至不会考虑手动删除[]。它很容易出错,而且不是异常安全的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 2016-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多