Reputation: 1246
From this link, I know that we(application) should always don't delete a heap memory allocation from dll, because the heap memory manager are different.
I have few questions:
1.) How about .so file (Linux), is it the same case ?
2.) Is there anyway to make sure that application and library(.dll and .so) are using same heap memory manager or using same heap memory section ? So we can delete and new separately (new at .dll/.so, delete at application ).
Thank you.
Upvotes: 6
Views: 796
Reputation: 1341
Library developers take care about this by implementing they own methods for freeing memory allocated inside of library. For example:
ipmi_fru_node_get_field
and ipmi_fru_data_free
.CertCreateCertificateContext
and CertFreeCertificateContext
Upvotes: 0
Reputation: 117408
1.) How about .so file (Linux), is it the same case ?
Yes, a library built using a different implementation of the Standard C++ Library than the program it's finally linked with may do allocations in a slightly different manner. g++
's libstdc++
and clang++
's libc++
are examples of two different implementations. They may be 100% ABI compatible - but a third unknown library may not be.
2.) Is there anyway to make sure that application and library(.dll and .so) are using same heap memory manager or using same heap memory section ? So we can delete and new separately (new at .dll/.so, delete at application ).
No, what's compiled into the library is what will be used by the library, unless there's a way to initialize the library upon loading it, telling it to use a specific heap manager.
Please explain in details. I wish to know for .so (Linux), is it using only one heap manager for both application and .so (library). Let's said, my application compiled by compiler version A, while my .so complied by compiler version B, is it still ok ?
Because of the reason mentioned above, no, you can't be sure. Since you are the library creator you could however make your API so that the new
and delete
memory allocations/deallocations for types in your library are delegated to member functions compiled into the library, which in turn does the real allocations/deallocations (described in operator new, operator new[]
and operator delete, operator delete[]). Pointers to objects of your types could then be new
ed and passed between the library and application and be delete
d on either side.
Here's an (incomplete) example of how that could look using a class-specific allocation function:
void* T::operator new(std::size_t count);
and a class-specific usual deallocation function:
void T::operator delete(void* ptr);
It contains foo.hpp
and foo.cpp
used to create libfoo.so
(or libfoo.a
) and code for a program using the library.
foo.hpp
#pragma once
#include <new>
class Foo {
public:
// The "usual" part of your class definition:
Foo(int x);
~Foo();
// This part does NOT get compiled into your library.
// It'll only be used by users of your library:
#ifndef BUILDING_LIB
// Note: operator new and delete are static by default
// single object allocation/deallocation:
void* operator new(std::size_t /* byte_count */) { return Alloc(); }
void operator delete(void* addr) { Free(addr); }
// array allocation/deallocation:
// TODO: operator new[] and delete[]
#endif
private:
int value;
// the functions really doing the memory management
static void* Alloc();
static void Free(void* p);
};
foo.cpp
// Define BUILDING_LIB to disable the proxy operator new/delete functions when building
// the library.
#define BUILDING_LIB
#include "foo.hpp"
#include <cstdlib> // std::aligned_alloc
#include <iostream>
Foo::Foo(int x) : value(x) {
std::cout << "Foo:Foo(" << value << ")\n";
}
Foo::~Foo() {
std::cout << "Foo:~Foo() " << value << "\n";
}
void* Foo::Alloc() {
void* addr = std::aligned_alloc(alignof(Foo), sizeof(Foo));
std::cout << "Alloc() " << sizeof(Foo) << "\t@ " << addr << '\n';
return addr;
}
void Foo::Free(void* addr) {
std::cout << "Free()\t\t@ " << addr << '\n';
std::free(addr);
}
uselib.cpp
#include "foo.hpp"
#include <memory>
int main() {
auto a = std::make_unique<Foo>(123); // heap allocation
// An automatic variable will use the applications memory manager and will not
// use Alloc/Free.
Foo b(456);
}
Possible output:
Alloc() 4 @ 0x1af7eb0
Foo:Foo(123)
Foo:Foo(456)
Foo:~Foo() 456
Foo:~Foo() 123
Free() @ 0x1af7eb0
Upvotes: 4
Reputation: 3968
The heap manager is located in static memory of the runtime library (msvcrXXX for Win and crt for Linux). You can use the runtime library in two ways: as static or dynamic. If you link the runtime as static to your own library, then you can't alloc in your library and free in another. But you link the runtime as dynamic, then you can alloc in your library and free in another.
Upvotes: 0
Reputation: 88
1) Symbol tables are shared across an entire process in Linux. malloc() for any part of the process is the same as all the other parts. So yes, if all parts of a process access the heap via malloc() et alia then they will share the same heap.
2) but second question i too have bit confusion.
Upvotes: 0