c++ - LocalAlloc 与 GlobalAlloc 与 malloc 与 new

标签 c++ winapi heap-memory

我已经在各种链接上搜索过这个,但仍然存在疑问。

我不明白 LocalAlloc vs GlobalAlloc vs malloc vs new 内存分配的区别。

我已经浏览了 MSDN 的这个链接:

Comparing Memory Allocation Methods

请解释以下语句:

The malloc function has the disadvantage of being run-time dependent. The new operator has the disadvantage of being compiler dependent and language dependent

最佳答案

摘自 Raymond Chen's OldNewThing

Back in the days of 16-bit Windows, the difference was significant.

In 16-bit Windows, memory was accessed through values called “selectors”, each of which could address up to 64K. There was a default selector called the “data selector”; operations on so-called “near pointers” were performed relative to the data selector. For example, if you had a near pointer p whose value was 0x1234 and your data selector was 0x012F, then when you wrote *p, you were accessing the memory at 012F:1234. (When you declared a pointer, it was near by default. You had to say FAR explicitly if you wanted a far pointer.)

Important: Near pointers are always relative to a selector, usually the data selector.

The GlobalAlloc function allocated a selector that could be used to access the amount of memory you requested. You could access the memory in that selector with a “far pointer”. A “far pointer” is a selector combined with a near pointer. (Remember that a near pointer is relative to a selector; when you combine the near pointer with an appropriate selector, you get a far pointer.)

Every instance of a program and DLL got its own data selector, known as the HINSTANCE. Therefore, if you had a near pointer p and accessed it via *p from a program executable, it accessed memory relative to the program instance’s HINSTANCE. If you accessed it from a DLL, you got memory relative to your DLL’s HINSTANCE.

Therefore, that in 16-bit Windows, the LocalAlloc and GlobalAlloc functions were completely different! LocalAlloc returned a near pointer, whereas GlobalAlloc returned a selector.

Pointers that you intended to pass between modules had to be in the form of “far pointers” because each module has a different default selector. If you wanted to transfer ownership of memory to another module, you had to use GlobalAlloc since that permitted the recipient to call GlobalFree to free it.

Even in Win32, you have to be careful not to confuse the local heap from the global heap. Memory allocated from one cannot be freed on the other. All the weirdness about near and far pointers disappeared with the transition to Win32. But the local heap functions and the global heap functions are nevertheless two distinct heap interfaces.

另外,link你指定的明确表示,

Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that call HeapAlloc using a handle to the process's default heap, and HeapAlloc can be instructed to raise an exception if memory could not be allocated, a capability not available with LocalAlloc.

对于您对 ma​​lloc 与 new 的混淆,Billy ONeal 的回答非常清楚地总结了这一点。

对于 malloc and HeapAlloc 的区别, David Heffernan 和 Luis Miguel Huapaya 的回答结合起来给出了完美的解决方案:

  • malloc 是可移植的,是标准的一部分。 malloc(和其他 C 运行时堆函数)依赖于模块,这意味着如果您在一个模块(即 DLL)的代码中调用 malloc,那么您应该调用 free 在同一模块的代码中,否则您可能会遭受一些非常严重的堆损坏。
  • HeapAlloc 不可移植,它是一个 Windows API 函数。使用 HeapAllocGetProcessHeap 而不是 malloc,包括重载 newdelete 运算符来利用这些,允许您在模块之间传递动态分配的对象,如果内存在一个模块的代码中分配并在另一个模块的代码中释放,一旦指向内存块的指针被传递,则不必担心内存损坏到外部模块。

关于c++ - LocalAlloc 与 GlobalAlloc 与 malloc 与 new,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34326835/

相关文章:

c++ - 在两个 channel 矩阵中插入数据

c++ - 更改 Code::Blocks 中的主要方法?

java - 如何判断java应用程序是否接近内存不足

C-在执行过程中检查特定的内存地址

c++ - 适用于 Windows 的免费轻量级 IDE/文本编辑器 - C++ 开发

c++ - while(i--) s+= a[i];在 C 和 C++ 中包含未定义的行为?

c - 使用 WinAPI 线程的 Winsock 服务器重置第一个连接

c++ - FindNextFile 因空格字符而失败

java - eclipse java中三种不同方法增加JVM堆内存失败

c++ - 读取 Firebird 存储过程的返回值