【问题标题】:In C++, can new in one thread allocate the memory deleted by another thread?在 C++ 中,一个线程中的 new 可以分配另一个线程删除的内存吗?
【发布时间】:2015-09-22 10:02:57
【问题描述】:

In glibc, malloc is implemented with arenas。 因此,例如,线程A中malloc和后来freed分配的内存可能不能被线程B中malloc的另一个调用使用,因为线程A和B可能在不同的arenas,不同的 arenas 维护着不同的堆和空闲内存列表。

说到 C++(也许还有 C++11,因为 C++11 有一个新标准),故事还是一样吗?

或者不同线程实际上共享同一个堆段和空闲内存列表,一个线程中的new可以先分配内存newed,然后deleted由另一个线程分配?

如果答案取决于实现,那么问题是它们在主要的 C++ 编译器中是如何实现的,例如 g++、MVC++、icc?

编辑

我认为这个问题是正确的,因为有时你会启动很多 线程,并且在每个线程中,您为大量对象动态分配/取消分配大量内存,并且您不希望应用程序的内存使用量高得离谱。

【问题讨论】:

  • C++ 没有说明分配函数是如何实现的,只说明它们必须产生什么结果。
  • 在实践中new 调用malloc。但目前尚不清楚您希望如何处理这些信息。
  • 你的意思是new是由malloc实现的?这是标准化的吗?
  • 不要不要为 C++ 问题添加 C 标记!
  • 为什么这被否决了?这不是关于 C++ 内存管理的有效问题吗?请解释!

标签: c++ multithreading c++11 memory-management dynamic-memory-allocation


【解决方案1】:

这个:

不同线程实际上共享同一个堆段和空闲内存列表,一个线程中的new可以分配先newed后被另一个线程删除的内存

线程的目的 - 共享内存空间。如果你不需要这个功能,你最好使用进程。

【讨论】:

  • 请注意,在 C 语言中,某个线程可访问的空闲内存空间可能无法被另一个线程访问。我问的是 C++ 中的行为,我不是在谈论跨不同线程访问变量之类的东西。
  • @Allanqunzi "某个线程可访问的空闲内存空间可能无法被另一个线程访问" 在哪里?在哪种情况下?
【解决方案2】:

C++ std 和你使用的分配器实现是两个不同的东西。如果你使用 gcc 来编译你的 C++ 代码,它默认使用 glibc 作为分配器。所以如果你的 gcc 是一个足够新的版本,它使用 glibc 和 per-thread arenas,你很高兴。

【讨论】:

    【解决方案3】:

    这取决于。在 Windows 上,不允许使用 DLL 的线程将在一个 DLL 中分配的内存所有权转移到另一个 DLL。所有新闻和删除必须在 DLL 的“同一侧”执行。虽然这不是严格的线程问题,但它仍然意味着一个线程不能简单地将内存所有权转移给任何其他线程而不知道内存的来源。

    Do (statically linked) DLLs use a different heap than the main program?

    【讨论】:

    • 没有“基于 DLL 的线程”之类的东西。 “new”在 DLL 中分配的内存不能通过“delete”在另一个 DLL 或主应用程序中释放 - 这与线程无关。
    • 我将措辞从“基于 DLL 的线程”更改为“使用 DLL 的线程”,这就是我的意思。
    • 如果 DLL 使用相同的编译器和标志进行编译,则释放在另一个 DLL 中分配的内存没有问题。
    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    相关资源
    最近更新 更多