I have searched for this on various links, but still the doubt persist.
我已经在各种链接上搜索过这个,但仍然存在疑问。
I do not understand the difference between LocalAlloc
vs GlobalAlloc
vs malloc
vs new
for memory allocation.
我不明白LocalAlloc与GlobalAlloc对比malloc与新内存分配之间的区别。
I have gone through this link of MSDN:
我已经浏览了MSDN的这个链接:
Comparing Memory Allocation Methods
比较内存分配方法
Please explain the following statement:
请解释以下声明:
The malloc function has the disadvantage of being run-time dependent. The new operator has the disadvantage of being compiler dependent and language dependent
malloc函数的缺点是依赖于运行时。新运算符的缺点是依赖于编译器和语言
2 个解决方案
#1
17
Excerpts from Raymond Chen's OldNewThing
摘自Raymond Chen的OldNewThing
Back in the days of 16-bit Windows, the difference was significant.
回到16位Windows的时代,差异显着。
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.)
在16位Windows中,通过称为“选择器”的值访问内存,每个值可以达到64K。有一个名为“数据选择器”的默认选择器;对数据选择器执行对所谓的“近指针”的操作。例如,如果你有一个近指针p,其值为0x1234而你的数据选择器是0x012F,那么当你写* p时,你正在访问012F:1234的内存。 (当你声明一个指针时,它默认接近。如果你想要一个远指针,你必须明确地说FAR。)
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.)
GlobalAlloc函数分配了一个选择器,可用于访问您请求的内存量。您可以使用“远指针”访问该选择器中的内存。 “远指针”是与近指针组合的选择器。 (请记住,near指针是相对于选择器的;当你将near指针与适当的选择器结合使用时,你得到一个远指针。)
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.
程序和DLL的每个实例都有自己的数据选择器,称为HINSTANCE。因此,如果您有一个近指针p并通过程序可执行文件中的* p访问它,它会访问相对于程序实例的HINSTANCE的内存。如果从DLL访问它,则会获得相对于DLL的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.
因此,在16位Windows中,LocalAlloc和GlobalAlloc功能完全不同! LocalAlloc返回一个near指针,而GlobalAlloc返回一个选择器。
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.
您打算在模块之间传递的指针必须采用“远指针”的形式,因为每个模块都有不同的默认选择器。如果您想将内存的所有权转移到另一个模块,则必须使用GlobalAlloc,因为这允许收件人调用GlobalFree来释放它。
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.
即使在Win32中,也必须小心不要将本地堆与全局堆混淆。从一个分配的内存不能在另一个上释放。随着过渡到Win32,所有关于近端和远端指针的怪异都消失了。但是本地堆函数和全局堆函数仍然是两个不同的堆接口。
Also, the link specified by you clearly says that,
此外,您指定的链接清楚地表明,
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.
从32位Windows开始,GlobalAlloc和LocalAlloc实现为包装函数,使用进程默认堆的句柄调用HeapAlloc,如果无法分配内存,可以指示HeapAlloc引发异常,这是LocalAlloc无法提供的功能。
For your confusion on malloc vs new, Billy ONeal's answer summarizes that pretty clearly.
对于你对malloc与new的混淆,Billy ONeal的回答非常清楚地总结了这一点。
For the difference between malloc and HeapAlloc, David Heffernan's and Luis Miguel Huapaya's answer combined gives the perfect solution::
对于malloc和HeapAlloc之间的区别,David Heffernan和Luis Miguel Huapaya的答案结合起来给出了完美的解决方案::
-
malloc
is portable, part of the standard.malloc
(and other C runtime heap functions) are module dependant, which means that if you callmalloc
in code from one module (i.e. a DLL), then you should callfree
within code of the same module or you could suffer some pretty bad heap corruption. -
HeapAlloc
is not portable, it's a Windows API function. UsingHeapAlloc
withGetProcessHeap
instead ofmalloc
, including overloadingnew
anddelete
operators to make use of such, allow you to pass dynamically allocated objects between modules and not have to worry about memory corruption if memory is allocated in code of one module and freed in code of another module once the pointer to a block of memory has been passed across to an external module.
malloc是便携式的,是标准的一部分。 malloc(和其他C运行时堆函数)是模块相关的,这意味着如果你从一个模块(即一个DLL)调用代码中的malloc,那么你应该在同一个模块的代码中调用free,否则你可能会遇到一些非常糟糕的堆腐败。
HeapAlloc不可移植,它是Windows API函数。使用HeapAlloc和GetProcessHeap而不是malloc,包括重载new和delete运算符来使用它们,允许你在模块之间传递动态分配的对象,如果内存在一个模块的代码中分配并在代码中释放,则不必担心内存损坏一旦指向内存块的指针已传递到外部模块,则为另一个模块。
#2
12
GlobalAlloc
and LocalAlloc
are old functions from the 16 bit era. The difference was that you sometimes had to be able to allocate memory only used in your segment (that used near pointers), and sometimes needed to allocate memory to be shared with other processes and segments on the system. Today, these guys forward in some form or another to the HeapXxx functions, such as HeapAlloc
. If you're writing new code and need to avoid linking with the C runtime, you should use the HeapXxx functions instead. Of course, if you call any of these, your program will only compile and run on Windows.
GlobalAlloc和LocalAlloc是16位时代的旧功能。不同之处在于,您有时必须能够分配仅在您的段中使用的内存(使用近指针),有时需要分配内存以与系统上的其他进程和段共享。今天,这些家伙以某种形式转发到HeapXxx功能,例如HeapAlloc。如果您正在编写新代码并且需要避免与C运行时链接,则应使用HeapXxx函数。当然,如果你调用其中任何一个,你的程序将只在Windows上编译和运行。
malloc
is "run-time dependent" in that using it requires that you link against the C run-time (CRT). The CRT is the library that contains all the other standard C library functions, like printf
or qsort
. You can write a plain Win32 API program without linking with this (but I honestly can't see why you'd want to do that in real software).
malloc是“运行时相关的”,因为使用它需要您链接C运行时(CRT)。 CRT是包含所有其他标准C库函数的库,如printf或qsort。您可以编写一个简单的Win32 API程序而不与此链接(但老实说,我不明白为什么您要在真实软件中这样做)。
new
is compiler dependent and language dependent in that they require a compiler that can compile C++. (And usually new
is implemented in terms of malloc
, so it'll probably require using the CRT as well)
new依赖于编译器和语言,因为它们需要一个可以编译C ++的编译器。 (通常新的是按照malloc实现的,所以它可能也需要使用CRT)
#1
17
Excerpts from Raymond Chen's OldNewThing
摘自Raymond Chen的OldNewThing
Back in the days of 16-bit Windows, the difference was significant.
回到16位Windows的时代,差异显着。
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.)
在16位Windows中,通过称为“选择器”的值访问内存,每个值可以达到64K。有一个名为“数据选择器”的默认选择器;对数据选择器执行对所谓的“近指针”的操作。例如,如果你有一个近指针p,其值为0x1234而你的数据选择器是0x012F,那么当你写* p时,你正在访问012F:1234的内存。 (当你声明一个指针时,它默认接近。如果你想要一个远指针,你必须明确地说FAR。)
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.)
GlobalAlloc函数分配了一个选择器,可用于访问您请求的内存量。您可以使用“远指针”访问该选择器中的内存。 “远指针”是与近指针组合的选择器。 (请记住,near指针是相对于选择器的;当你将near指针与适当的选择器结合使用时,你得到一个远指针。)
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.
程序和DLL的每个实例都有自己的数据选择器,称为HINSTANCE。因此,如果您有一个近指针p并通过程序可执行文件中的* p访问它,它会访问相对于程序实例的HINSTANCE的内存。如果从DLL访问它,则会获得相对于DLL的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.
因此,在16位Windows中,LocalAlloc和GlobalAlloc功能完全不同! LocalAlloc返回一个near指针,而GlobalAlloc返回一个选择器。
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.
您打算在模块之间传递的指针必须采用“远指针”的形式,因为每个模块都有不同的默认选择器。如果您想将内存的所有权转移到另一个模块,则必须使用GlobalAlloc,因为这允许收件人调用GlobalFree来释放它。
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.
即使在Win32中,也必须小心不要将本地堆与全局堆混淆。从一个分配的内存不能在另一个上释放。随着过渡到Win32,所有关于近端和远端指针的怪异都消失了。但是本地堆函数和全局堆函数仍然是两个不同的堆接口。
Also, the link specified by you clearly says that,
此外,您指定的链接清楚地表明,
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.
从32位Windows开始,GlobalAlloc和LocalAlloc实现为包装函数,使用进程默认堆的句柄调用HeapAlloc,如果无法分配内存,可以指示HeapAlloc引发异常,这是LocalAlloc无法提供的功能。
For your confusion on malloc vs new, Billy ONeal's answer summarizes that pretty clearly.
对于你对malloc与new的混淆,Billy ONeal的回答非常清楚地总结了这一点。
For the difference between malloc and HeapAlloc, David Heffernan's and Luis Miguel Huapaya's answer combined gives the perfect solution::
对于malloc和HeapAlloc之间的区别,David Heffernan和Luis Miguel Huapaya的答案结合起来给出了完美的解决方案::
-
malloc
is portable, part of the standard.malloc
(and other C runtime heap functions) are module dependant, which means that if you callmalloc
in code from one module (i.e. a DLL), then you should callfree
within code of the same module or you could suffer some pretty bad heap corruption. -
HeapAlloc
is not portable, it's a Windows API function. UsingHeapAlloc
withGetProcessHeap
instead ofmalloc
, including overloadingnew
anddelete
operators to make use of such, allow you to pass dynamically allocated objects between modules and not have to worry about memory corruption if memory is allocated in code of one module and freed in code of another module once the pointer to a block of memory has been passed across to an external module.
malloc是便携式的,是标准的一部分。 malloc(和其他C运行时堆函数)是模块相关的,这意味着如果你从一个模块(即一个DLL)调用代码中的malloc,那么你应该在同一个模块的代码中调用free,否则你可能会遇到一些非常糟糕的堆腐败。
HeapAlloc不可移植,它是Windows API函数。使用HeapAlloc和GetProcessHeap而不是malloc,包括重载new和delete运算符来使用它们,允许你在模块之间传递动态分配的对象,如果内存在一个模块的代码中分配并在代码中释放,则不必担心内存损坏一旦指向内存块的指针已传递到外部模块,则为另一个模块。
#2
12
GlobalAlloc
and LocalAlloc
are old functions from the 16 bit era. The difference was that you sometimes had to be able to allocate memory only used in your segment (that used near pointers), and sometimes needed to allocate memory to be shared with other processes and segments on the system. Today, these guys forward in some form or another to the HeapXxx functions, such as HeapAlloc
. If you're writing new code and need to avoid linking with the C runtime, you should use the HeapXxx functions instead. Of course, if you call any of these, your program will only compile and run on Windows.
GlobalAlloc和LocalAlloc是16位时代的旧功能。不同之处在于,您有时必须能够分配仅在您的段中使用的内存(使用近指针),有时需要分配内存以与系统上的其他进程和段共享。今天,这些家伙以某种形式转发到HeapXxx功能,例如HeapAlloc。如果您正在编写新代码并且需要避免与C运行时链接,则应使用HeapXxx函数。当然,如果你调用其中任何一个,你的程序将只在Windows上编译和运行。
malloc
is "run-time dependent" in that using it requires that you link against the C run-time (CRT). The CRT is the library that contains all the other standard C library functions, like printf
or qsort
. You can write a plain Win32 API program without linking with this (but I honestly can't see why you'd want to do that in real software).
malloc是“运行时相关的”,因为使用它需要您链接C运行时(CRT)。 CRT是包含所有其他标准C库函数的库,如printf或qsort。您可以编写一个简单的Win32 API程序而不与此链接(但老实说,我不明白为什么您要在真实软件中这样做)。
new
is compiler dependent and language dependent in that they require a compiler that can compile C++. (And usually new
is implemented in terms of malloc
, so it'll probably require using the CRT as well)
new依赖于编译器和语言,因为它们需要一个可以编译C ++的编译器。 (通常新的是按照malloc实现的,所以它可能也需要使用CRT)