LocalAlloc Vs GlobalAlloc Vs malloc Vs new - c++

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.
I have gone through this link of 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

Excerpts from 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.
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.
For your confusion on malloc vs new, Billy ONeal's answer summarizes that pretty clearly.
For the difference between malloc and HeapAlloc,
David Heffernan's and Luis Miguel Huapaya's answer combined gives the perfect solution::
malloc is portable, part of the standard. malloc (and other C runtime heap functions) are module dependant, which means that if you call malloc in code from one module (i.e. a DLL), then you should call free 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. Using HeapAlloc with GetProcessHeap instead of malloc, including overloading new and delete 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.

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.
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).
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)

Related

Memory Leak Detectors Working Principle

How do memory leak detectors actually work? What are the underlying concepts in general? Can take C++ as the language to explain this.
There are a couple of different ways that leak detectors work. You can replace the implementation of malloc and free with ones that can track more information during allocation and are not concerned with performance. This is similar to how dmalloc works. In general, any address that is malloc'ed but not free'd is leaked.
The basic implementation is actually pretty simple. You just maintain a lookup table of every allocation and its line number, and remove the entry when it is freed. Then when the program is done you can list all leaked memory. The hard part is determining when and where the allocation should have been freed. This is even harder when there are multiple pointers to the same address.
In practice, you'll probably want more than just the single line number, but rather a stack trace for the lost allocations.
Another approach is how valgrind works which implements an entire virtual machine to keep track of addresses and memory references and associated bookkeeping. The valgrind approach is much more expensive, but also much more effective as it can also tell you about other types of memory errors like out of bounds reads or writes.
Valgrind essentially instruments the underlying instructions and can track when a given memory address has no more references. It can do this by tracking assignments of addresses, and so it can tell you not just that a piece of memory was lost, but exactly when it became lost.
C++ makes things a little harder for both types of leak detectors because it adds the new and delete operators. Technically new can be a completely different source of memory than malloc. However, in practice many real C++ implementations just use malloc to implement new or have an option to use malloc instead of the alternate approach.
Also higher level languages like C++ tend to have alternative higher level ways of allocating memory like std::vector or std::list. A basic leak detector would report the potentially many allocations made by the higher level modes separately. That's much less useful than saying the entire container was lost.
Here's a published technical paper on how our CheckPointer tool works.
Fundamentally it tracks the lifetimes of all values (heap and stack), and their sizes according their types as defined by the language. This allows CheckPointer to find not only leaks, but out-of-array bound accesses, even for arrays in the stack, which valgrind won't do.
In particular, it analyzes the source code to find all pointer uses.
(This is quite the task just by itself).
It keeps track of pointer meta data for each pointer, consisting of
A reference to the object meta data for the heap-allocated object or global or local variable orfunction pointed to by the pointer and
The address range of the (sub)object of the object that the pointer may currently access. This may be smaller than the address range of the
whole object; e.g. if you take the address of a struct member, the instrumented source code will only allow access to that member when using the resulting pointer.
It also tracks the kind and location of each object, i.e. whether
it is a function, a global, thread-local or local variable, heap-allocated memory, or a string literal constant:
The address range of the object that may be safely accessed, and
For each pointer stored in the heap-allocated object or variable, a reference to the pointer metadata for that pointer.
All this tracking is accomplished by transforming the original program source, into a program which does what the original program does, and interleaves various meta-data checking or updating routines. The resulting program is compiled and run. Where a meta-data check fails at runtime, a backtrace is provided with a report of the type of failure (invalid pointer, pointer outside valid bounds, ...)
This is tagged C and C++ and no operating system is mentioned. This answer is for Windows.
C
Windows has the concept of virtual memory. Any memory a process can get is virtual memory. This is done through VirtualAlloc() [MSDN]. You can imagine the leak detector to put a breakpoint on that function and whenever it is called, it gets the callstack and saves it somewhere. Then it can do similar for VirtualFree()[MSDN].
The difference can then be identified and shown along with the callstacks that have been saved.
C++
C++ has a different concept: it takes the large 64kb blocks which it gets from VirtualAlloc() and splits it into smaller pieces, called the Heap. The C++ heap manager comes from Microsoft and offers new methods HeapAlloc() [MSDN] and HeapFree()[MSDN].
Then, you could do the same as before, but actually, that feature is already built-in. Microsoft's GFlags [MSDN] tool can enable the tracking:
In this case it will save up to 50 MB of callstack information for C++ heap manager calls.
Since that settings can also be enabled via the Windows Registry, a memory leak detector can make use of it easily.
General concept
As you can see, the general concept is to keep track of allocations and deallocations, compare them and show the callstacks of the difference.

Is it bad practice to allocate memory in a DLL and give a pointer to it to a client app?

I'm using an exe which dynamically loads a DLL. A function in the DLL allocates memory on the heap and passes a pointer to that memory to the exe.
A senior says that it is bad practice to do so. He says that if I ever have to share memory between the exe and the DLL, the exe has to allocate memory and pass a pointer to that to the DLL, and not vice versa. Is this true? Why?
EDIT: In my case, I planned to allocate and deallocate memory inside the DLL itself.
Here are some reasons for having the caller supply a pointer:
Symmetric ownership semantics. This is already explained by several other answers.
Avoids mismatching the allocator and deallocator. As mentioned in Aesthete's answer, if the DLL allocates a pointer and returns it, the caller must call the corresponding deallocator to free it. This is not necessarily trivial: the DLL might be statically linked against one version of, say, malloc/free while the .exe is linked against a different version of malloc/free. (For example, the DLL could be using release versions while the .exe is using specialized debug versions.)
Flexibility. If the DLL is meant for general use, having the caller allocate the memory gives the caller more options. Suppose the caller doesn't want to use malloc and instead wants memory to be allocated from some specific memory pool. Maybe it's a case where the caller could provide a pointer to memory allocated on the stack. If the DLL allocated the memory itself, the caller does not have any of these options.
(The second and third points also mostly can be addressed by having the .exe supply an allocator/deallocator for the DLL code to use.)
One of the basic idea behind the design patterns is ownership. The idea is - one who creates a resource (and thereby holds it in the pointer) should be responsible for deleting the resource. This will ensure the sanctity of the design and in longer life of the projects, its developer can see lesser bugs.
So now it in your case, the DLL can be attached by any executable and he can try to delete the resource, which may cause future problem. So I think it has been suggested for vice-versa and I would say it as a sound advice.
I have seen this issue before, and it is caused by the DLL and exe linking differently to the CRT (static, dynamic MT etc).
I you're going to pass a pointer to memory between DLL and executable, they should both provide some sort of Free() functionality to free memory from their respective heaps.
Generally, the heap (The One Heap) belongs to the process, and it does not matter where you allocate from, so this will work just fine, except when it doesn't.
Therefore, the claim that it is "bad practice" is valid. There are few things that are worse than something that works fine, except when it doesn't.
The worst part about it is that when everything blows up, it's not immediately obvious what's wrong, and you can easily run into an issue without knowing. It may be something as easy as linking the a particular version of the CRT into your DLL. Or someone in your team might have created a separate heap for some reason. Or, some other reason that isn't immediately obvious which caused another heap being created.
What makes the free-from-wrong-heap situation so vicious is that you don't generally know what will happen, or when (or if someone will notice).
You may get a NULL return value from a heap function or an exception. Your application might be prepared for either of them or it might not be (be honest, you always check return values, don't you?). It might crash immediately upon freeing, or you might just silently leak memory and run out of address space (or memory) minutes or hours later, and nobody will know why. Or, something else.
Thus, what you see may not at all be in (apparent) correlation to what caused the problem.
I only want to point out that passing an allocator to the DLL to allocate memory is perfectly safe and is the standard model used by the C++ std library itself. In this case, the allocation is done by the DLL via a method passed from the caller, avoiding to pass pointers, and avoiding the issue of linking to different implementations of malloc().
the exe and the dll may have different heaps. when either try to free memory allocated by the other the free fails and there is a leak.
only if both, the exe and the dll use CRT dynamically with the same version of the CRT they use the same heap.
so it is a very good advice to do allocation and free in the same binary.
As #kumar_m_kiran already pointed out, it's about ownership issue, however I want to note, that #aleguna is correct too, therefore, imho, correct rule is "Either allocate and deallocate same memory in DLL or in EXE, but not in both".
I'd argue that it is generally bad practice to hand around raw pointers. In case of a dll, it should return a smart-pointer that has a custom deleter that appropriately handles the cleanup (options are std::unique_ptr, std::shared_ptr or boost::shared_ptr in order of preference).
In fact, it is probably safer to use std::weak_ptr or boost::weak_ptr - these require you to check each time you want to access the resource, because the dll might have been unloaded in the meantime.
It's not necessarily bad practice but it's dangerous practice (and probably bad). You need to carefully think about who is responsible for freeing the memory. The exe will probably not be able to (or should not be able to) free the DLL's memory directly itself so presumably will be passing this pointer back to the DLL at some later date. So now we're passing a pointer back and forth between an EXE and a DLL which isn't nice.
I'd say no, it's not "bad practice". From my experience, you just need to be careful that you release that pointer in the right memory space. I've built a graphics engine that allocated assets in multiple DLLs (each DLL represented a mini game); using a shared_ptr (at the time it was Boost, however, I'm sure the C++11 (or newer) std::shared_ptr supports the same semantics). I would supply a function that would delete the memory in the right space. The main concern, at this point, is that you ensure you free your shared_ptrs before you free the DLL. I can't recall now, but we might have used a list of shared_ptrs owned by the DLL/DLL wrapper, and all other uses of the pointer were through a weak_ptr TO that shared_ptr.

Issues when memory allocation/deallocation when linking with static c runtime

I came across below note in the book Windows via C-C++ by Jeffrey Richter and Christophe Nasarre.
Examine the following code:
V
OID EXEFunc() {
PVOID pv = DLLFunc();
// Access the storage pointed to by pv...
// Assumes that pv is in EXE's C/C++ run-time heap
free(pv);
}
PVOID DLLFunc() {
// Allocate block from DLL's C/C++ run-time heap
return(malloc(100));
}
So, what do you think? Does the preceding code work correctly? Is the block allocated by the
DLL's function freed by the EXE's function? The answer is: maybe. The code shown does not
give you enough information. If both the EXE and the DLL link to the DLL C/C++ run-time
library, the code works just fine. However, if one or both of the modules link to the static C/C++
run-time library, the call to free fails.
I'm not able to understand why call to free would fail here when linking modules with static C runtime.
Can someone explain why free fails?
Found similar question here:
Memory Allocation in Static vs Dynamic Linking of C Runtime
But I've same doubt here as MrPhilTx:
Wouldn't all of the heaps be in the same address space?
Thanks!
When both your DLL and EXE are staticly linked to the C runtime the two runtimes simply don't know about each other. So both the EXE and DLL get their own copy of the runtime, their own heap and heap metadata. Neither side knows about the others Metadata and there is no safe way to update the data when you free memory. You end up with inconstant metadata and things will eventually fail (and if your very lucky, it will fail right away).
What this means is that you end up with at least two heaps in your process, and each heap has it's own rules and metadata. There is no way for the EXE to know the exact way the DLL allocates memory so there is no way for it to free it.
As for why you can get away with sharing a heap when everything is dynamically linked, that's easy, there is only one copy of the C Runtime DLL in the process, so if every DLL links against it they will all be calling the same code with the same metadata.
You can't allocate memory from one allocator and free it with another. Different allocators use different internal implementations and the result of giving a memory block to an allocator that didn't allocate it is unpredictable.
So unless you know for a fact that two sections of code are using the same allocator, you can't allocate memory in one section of code and free it in the other. The usual solution is to ensure the same unit both allocates and frees the memory. In your example, the DLL could offer a "free" function that the main code could call into instead of calling its own free function which frees to its own allocator.
So do this instead:
OID EXEFunc() {
PVOID pv = DLLFunc();
// Access the storage pointed to by pv...
// Assumes that pv is in EXE's C/C++ run-time heap
DLLFreeFunc(pv);
}
...
PVOID DLLFunc() {
// Allocate block from DLL's C/C++ run-time heap
return(malloc(100));
}
DLLFreeFunc(PVOID x) {
free(x);
}
On Linux, a program uses the brk and sbrk system calls to request extra data pages from the kernel. sbrk returns an address pointing to the data segment that can be used by your program.
malloc and free use the data segment returned by brk and sbrk by turning it into a heap. The heaps is a large block of memory in the current porcess's space which small blocks of memory can be requested and returned as required. It is important to note that many calls to malloc and free will make no system calls.
Now when malloc and free want to make use of the heap they need to get a pointer to the heap. This pointer is stored in a separate data segment called static data and is allocated when the application loads. In order to insure that different DLLs (or shared libraries on linux) to no clash with eachother, each DLL has its own static data sections.
Now let us assume that both the dll and the executable are statically linked to their own libraries. In such a case the dll and the executable will have pointers to a different heaps and is such event both dll and executable must free their own memory.
However on linux both the dll and the executable will access malloc and free through a common DLL (libc.so on linux). In such a case, since both the dll and executable are effectively accessing libc's heap, the executable can safely free memory allocated by the dll.
In any event it is good practice for the dll to provide its own free function. This if nothing else documents that the pointer returned by DLLFunc needs to be freed.
I imagine this is true on Windows as well.
The code critically depends on the implementation of malloc and free. A good implementation has no issues, a poor one will indeed fail. It's definitely easier to create a working DLL implementation of malloc and free, but it's far from impossible to do so in a static library.
A trivial example would be a static library which forwards the calls directly to GlobalAlloc and GlobalFree.

Is it safe to allocate memory for buffers on external dll and use it on main application?

As in topic.. I've found something like this in one application. In main C application we have declaration:
void* buff = NULL;
and later there is a call:
ReadData(&buff);
SaveToFile(buff);
SaveToFile() is a C function from main function.
ReadData(void* * ) is a C++ function from external dll. In this function memory for buffer is allocated by malloc function and filed with data.
So here is my question: is it correct?
All modules in a running process share the same address space (doesn't care whether you're Windows or Linux or whatever actually, it's a common principle). However, be careful: reading or writing from module A to a buffer owned by module B is fine - but freeing the buffer is probably bad.
On Windows, it depends on the runtime library the application is linked against. If it is not the DLL runtime ('multithreaded dll'), every module maintains its own copy of the heap manager. Thus, the module that allocated a memory area must also be responsible for destroying it because only its own heap manager knows about it. If you follow this guideline, you won't run into problems (linking against the DLL runtime avoids the problem because all modules deal with the same heap manager residing somewhere in msvXXXnnn.dll, but gives rise to other issues).
Edit:
ReadData(void* * ) is a C++ function from external dll. In this function memory for buffer is allocated by malloc function and filed with data.
That might run into the aforementioned allocator issue. Either add another function to that DLL (FreeData) which is explicitly responsible for freeing up the buffer (as proposed by Neil Butterworth) and just calls its own free(). Or you add a DLL function to query the size of the buffer, allocate it upfront and pass it to ReadData (that's the cleanest choice imo).
If both the DLL and the main executable were linked with the same C runtime, this is OK and you can call free() on the pointer to release it. However, a better idea is in the DLL to provide a function FreeData( void * ) which releases the data. In this way all memory management is done in the context of the DLL.
It's safe. However, you should always check:
if the same allocator is used for both allocation and deallocation
who is responsible for freeing (so there are no surprises)
watch out for any kind of automatic memory magement (if it's plain C/C++ then it's no problem).
It depends on the intention of the design and users the library is directed to. A better way is to take a buffer of some fixed size and fill it and return. But, you should be careful while freeing the buffer. It is better to call the free function (if any) provided by the third party DLL itself rather than calling free from your main.
In case of windows, if your third party DLL is using a different heap and if your application is using a different heap, it might lead to undefined behaviour. For Ex: if your third party DLL is build using VC8 and your application is built using VC6, then if you free the memory allocated by your external DLL, it will lead to problems.
Yes, this is correct. Memory in a process is equally accessible by all modules (EXE and DLLs) in that process.
Yes, there is no problem with this.

How does sbrk() work in C++?

Where can I read about sbrk() in some detail?
How does it exactly work?
In what situations would I want to use sbrk() instead of the cumbersome malloc() and new()?
btw, what is the expansion for sbrk()?
Have a look at the specification for brk/sbrk.
The call basically asks the OS to allocate some more memory for the application by incrementing the previous "break value" by a certain amount. This amount (the first parameter) is the amount of extra memory your application then gets.
Most rudimentary malloc implementations build upon the sbrk system call to get blocks of memory that they split up and track. The mmap function is generally accepted as a better choice (which is why mallocs like dlmalloc support both with an #ifdef).
As for "how it works", an sbrk at its most simplest level could look something like this:
uintptr_t current_break; // Some global variable for your application.
// This would probably be properly tracked by the OS for the process
void *sbrk(intptr_t incr)
{
uintptr_t old_break = current_break;
current_break += incr;
return (void*) old_break;
}
Modern operating systems would do far more, such as map pages into the address space and add tracking information for each block of memory allocated.
sbrk is pretty much obsolete, these days you'd use mmap to map some pages out of /dev/zero. It certainly isn't something you use instead of malloc and friends, it's more a way of implementing those. Also, of course, it exists only on posix-based operating systems that care about backwards compatibility to ancient code.
If you find Malloc and New too cumbersome, you should look into garbage collection instead... but beware, there is a potential performance cost to that, so you need to understand what you are doing.
You never want to use sbrk instead of malloc or free. It is non-portable and is typically used only by implementers of the standard C library or in cases where it's not available. It's described pretty well in its man page:
Description
brk() sets the end of the
data segment to the value specified by
end_data_segment, when that value is
reasonable, the system does have
enough memory and the process does not
exceed its max data size (see
setrlimit(2)).
sbrk() increments the program's data
space by increment bytes. sbrk() isn't
a system call, it is just a C library
wrapper. Calling sbrk() with an
increment of 0 can be used to find the
current location of the program break.
Return Value
On success, brk() returns
zero, and sbrk() returns a pointer to
the start of the new area. On error,
-1 is returned, and errno is set to ENOMEM.
Finally,malloc and free are not cumbersome - they are the standard way to allocate and release memory in C. Even if you want to implement your own memory allocator, it's best to just use malloc and free as the basis - a common approach is to allocate a large chunk at a time with malloc and provide memory allocation from it (this is what suballocators, or pools, usually implement)
Re the origin of the name sbrk (or its cousin brk), it may have something to do with the fact that the end of the heap is marked by a pointer known as the "break". The heap starts right after the BSS segments and typically grows up towards the stack.
You've tagged this C++ so why would you use 'cumbersome' malloc() rather than new? I am not sure what is cumbersome about malloc in any case; internally maybe so, but why would you care? And if you did care (for reasons of determinism for example), you could allocate a large pool and implement your own allocator for that pool. In C++ of course you can overload the new operator to do that.
sbrk is used to glue the C library to the underlying system's OS memory management. So make OS calls rather than using sbrk(). As to how it works, that is system dependent. If for example you are using the Newlib C library (commonly used on 'bare-metal' embedded systems with the GNU compiler), you have to implement sbrk yourself, so how it works in those circumstances is up to you so long as it achieves its required behaviour of extending the heap or failing.
As you can see from the link, it does not do much and would be extremely cumbersome to use directly - you'd probably end-up wrapping it in all the functionality that malloc and new provide in any case.
This depends on what you mean by malloc being "Cumbersome". sbrk is typically not used directly anymore, unless you're implementing your own memory allocator: IE, operator overriding "new". Even then I'd possibly use malloc to give me my initial memory.
If you'd like to see how to to implement malloc() on top of sbrk(), check out http://web.ics.purdue.edu/~cs354/labs/lab6/ which is an exercise going through that.
On a modern system you shouldn't touch this interface, though. Since you're calling malloc and new cumbersome, I suspect you don't have all the requisite experience to safely and properly use sbrk for your code.