No. There is only 1 heap.
The reason some libraries can’t deallocate allocations made by other libraries is because each library puts meta-data before an allocation to tell it how much has been allocated and etc.
That's correct for Linux/Unix. For Windows (which this seems to be about), as a blanket statement, this is wrong (although the part about metadata is correct).
DLLs do not necessarily have their own heap, but they are allowed to create one, and some indeed do. This creates a "private" heap which reserves a contiguous area of address space (explained in the Remarks section here) with a handle different from the one returned by GetProcessHeap.
One notable example is Microsoft's CRT (and hence any library that dynamically links against it), which will lead to problems if you mix statically linked executables with dynamically linked DLLs, as outlined for example here. The bottom line is that the linker is smart enough not to let you mix the two CRTs in the executable, but it is possible (and in principle legitmate, and undetectable for the linker) to have some other DLL linked to a different CRT than the main program, and boom.
Other DLLs may create private heaps because the default heap is the "classic" one, not the "low fragmentation" version on Windows versions up to 7 (I may be lying here, it might be Win7 inclusive, not sure...). For some libraries, it may make sense to request the low fragmentation heap.
SQLite is one example of a library that calls HeapCreate.
In addition to that, every compiler (that includes different versions of the same compiler that use a different ABI, such as e.g. GCC/MingW 4.7 ? 4.8) adds some metadata to allocations. When you write something like new or delete in your program, this usually maps to malloc and free, plus calling constructors and destructors (the C++ standard does not say that, so this is in principle not correct, also you could overload operators, but it is correct in practice).
malloc and free, on their part, do some voodoo (usually something like add 4 bytes for the allocation length, and then round up to 8-byte alignment, which is the "real" address they'll return and accept), and call HeapAlloc and HeapFree. Whatever they do is not specified and may vary among compilers.
So, in short, you can't expect that deleting something will work reliably (it might work, accidentially!) if the whole combination of compiler plus module is not 100% identical in respect to how the object was allocated.
So if I create a structure like so:
struct Blob
{
unsigned char* pData;// std::vector< unsigned char > Data
size_t Length;
};
(Would the vector dealoccate itself from the right heap?)
The vector will, depending on the situation, call the standard allocator's deallocate function or operator delete, which may in fact do nothing (it might put the memory block on a free list) or which may eventually -- possibly via a roundtrip through free()-- call HeapFree. It will not magically figure out the correct heap, if there are several ones.
By the way, I'm not quite sure what the intent is with that raw pointer, the length, and the vector. In any case, the vector would need to have a "life" in some other place, or the raw pointer could not possibly be valid (if you do something that causes the vector to resize, it won't stay valid either). There's probably an easier and safer way of doing the same thing, such as using blob = std::vector<unsigned char>; -- vector already knows its length (size) and data() is always a valid pointer.