(C++) I have memory aligned instances allocated on heap, then delete them in another thread. The codes look like this:
ALIGNED class Obj
{
public: ALIGNED_NEW_DELETE
...
};
Thread 1:
Obj *o = new Obj; // overloaded new for aligned memory allocation
postTask(o);
Thread 2:
o->runTask();
delete o; // overloaded delete for aligned memory deletion
// "delete" statement crashes
The delete statement in thread 2 will give an assertion error in Visual Studio 2013 (_BLOCK_TYPE_IS_VALID).
Strangely, if i delete the object in the creation thread, everything runs fine.
Why does this happen? What's the solution?
EDIT:
#galop1n: Actually what i am currently using is Eigen's built-in new/delete operators EIGEN_MAKE_ALIGNED_OPERATOR_NEW. I also tried my own operators, both failed.
For Eigen's operators, please look up its source yourself.
For my allocators:
void* operator new(size_t size){ return alignedMalloc(size, align); }
void operator delete(void* ptr) { alignedFree(ptr); }
void* operator new[](size_t size) { return alignedMalloc(size, align); }
void operator delete[](void* ptr) { alignedFree(ptr); }
void* alignedMalloc(size_t size, size_t align)
{
char* base = (char*)malloc(size + align + sizeof(int));
if (base == nullptr)
ASSERT(0, "memory allocation failed");
char* unaligned = base + sizeof(int);
char* aligned = unaligned + align - ((size_t)unaligned & (align - 1));
((int*)aligned)[-1] = (int)((size_t)aligned - (size_t)base);
return aligned;
}
void alignedFree(const void* ptr) {
int ofs = ((int*)ptr)[-1];
free((char*)ptr - ofs);
}
And the ALIGNED macro is __declspec(align(16)). It crashes with or without the "ALIGNED" attribute.
This is awkward, the problem is in Thread 2, The Obj* is casted into a base class' pointer Task*, and for the utter stupidity: ~Task() is not virtual:
class Task
{
public:
~Task(); // <-- not virtual, therefore it crashes
...
}
ALIGNED class Obj : public Task
{ ... }
Should have discovered this problem much much earlier. Because, as in my description of the problem, i said it myself it gives an assertion error: _BLOCK_TYPE_IS_VALID, this is a visual studio debug lib's stuff for the default delete operator, which means it didn't even run into my overloaded delete operator, which ultimately means I missed a "virtual".
It's my bad that i even forgot to add the class inheritance to the question.
Sometimes, i can be stuck at a problem for hours or even days. But after i posted the issue online, i can immediately find the answer. Dunno if any of you have similar problems before; perhaps i've put too much stress onto myself.
Still, thanks you, Internet.
Related
I am working on an open-source library that has a memory leak in it. The library is a data streaming service built around boost::asio. The server side uses heap memory management system which provides memory to hold a finite number of samples while they wait to get pushed accross a tcp connection. When the server is first constructed, a heap of memory for all the old samples is allocated. From this heap, after a sample is passed accross the socket, the memory is returned to the heap.
This is fine, unless all that pre-allocated heap is already taken. Here is the function that creates a 'sample':
sample_p new_sample(double timestamp, bool pushthrough) {
sample *result = pop_freelist();
if (!result){
result = new(new char[sample_size_]) sample(fmt_, num_chans_, this);
}
return sample_p(result);
}
sample_p is just a typedef'd smart pointer templated to the sample class.
The offending line is in the middle. When there isn't a chunk of memory on the freelist, we need to make some. This leaks memory.
My question is why is this happening? Since I shove the new sample into a smart pointer, shouldn't the memory be freed when it goes out of scope (it gets popped off of a stack later on.)? Do I need to somehow handle the memory allocated on the inside---i.e. the memory allocated by new char[sample_size_]? If yes, how can I do that?
Edit:
#RichardHodges here is a compile-able MCVE. This is highly simplified but I think it captures exactly the problem I am facing in the original code.
#include <boost/intrusive_ptr.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
typedef boost::intrusive_ptr<class sample> sample_p;
typedef boost::lockfree::spsc_queue<sample_p> buffer;
class sample {
public:
double data;
class factory{
public:
friend class sample;
sample_p new_sample(int size, double data) {
sample* result = new(new char[size]) sample(data);
return sample_p(result);
}
};
sample(double d) {
data = d;
}
void operator delete(void *x) {
delete[](char*)x;
}
/// Increment ref count.
friend void intrusive_ptr_add_ref(sample *s) {
}
/// Decrement ref count and reclaim if unreferenced.
friend void intrusive_ptr_release(sample *s) {
}
};
void push_sample(buffer &buff, const sample_p &samp) {
while (!buff.push(samp)) {
sample_p dummy;
buff.pop(dummy);
}
}
int main(void){
buffer buff(1);
sample::factory factory_;
for (int i = 0; i < 10; i++)
push_sample(buff, factory_.new_sample(100,0.0));
std::cout << "press any key to exit" << std::endl;
char foo;
std::cin >> foo;
return 0;
}
When I step through the code, I note that my delete operator never gets called on the sample pointers. I guess that the library I'm working on (which again, I didn't write, so I am still learning its ways) is mis-using the intrusive_ptr type.
You are allocating the memory with new[] so you need to deallocate it with delete[] (on a char*). The smart pointer probably calls delete by default, so you should provide a custom deleter that calls delete[] (after manually invoking the destructor of the sample). Here is an example using std::shared_ptr.
auto s = std::shared_ptr<sample>(
new (new char[sizeof(sample)]) sample,
[](sample* p) {
p->~sample();
delete[] reinterpret_cast<char*>(p);
}
);
However, why you are using placement new when your buffer only contains one object? Why not just use regular new instead?
auto s = std::shared_ptr<sample>(new sample);
Or even better (with std::shared_ptr), use a factory function.
auto s = std::make_shared<sample>();
Example:
bool isHeapPtr(void* ptr)
{
//...
}
int iStack = 35;
int *ptrStack = &iStack;
bool isHeapPointer1 = isHeapPtr(ptrStack); // Should be false
bool isHeapPointer2 = isHeapPtr(new int(5)); // Should be true
/* I know... it is a memory leak */
Why, I want to know this:
If I have in a class a member-pointer and I don't know if the pointing object is new-allocated. Then I should use such a utility to know if I have to delete the pointer.
But:
My design isn't made yet. So, I will program it that way I always have to delete it. I'm going to avoid rubbish programming
There is no way of doing this - and if you need to do it, there is something wrong with your design. There is a discussion of why you can't do this in More Effective C++.
In the general case, you're out of luck, I'm afraid - since pointers can have any value, there's no way to tell them apart. If you had knowledge of your stack start address and size (from your TCB in an embedded operating system, for example), you might be able to do it. Something like:
stackBase = myTCB->stackBase;
stackSize = myTCB->stackSize;
if ((ptrStack < stackBase) && (ptrStack > (stackBase - stackSize)))
isStackPointer1 = TRUE;
The only "good" solution I can think of is to overload operator new for that class and track it. Something like this (brain compiled code):
class T {
public:
void *operator new(size_t n) {
void *p = ::operator new(n);
heap_track().insert(p);
return p;
}
void operator delete(void* p) {
heap_track().erase(p);
::operator delete(p);
}
private:
// a function to avoid static initialization order fiasco
static std::set<void*>& heap_track() {
static std::set<void*> s_;
return s_;
}
public:
static bool is_heap(void *p) {
return heap_track().find(p) != heap_track().end();
}
};
Then you can do stuff like this:
T *x = new X;
if(T::is_heap(x)) {
delete x;
}
However, I would advise against a design which requires you to be able to ask if something was allocated on the heap.
Well, get out your assembler book, and compare your pointer's address to the stack-pointer:
int64_t x = 0;
asm("movq %%rsp, %0;" : "=r" (x) );
if ( myPtr < x ) {
...in heap...
}
Now x would contain the address to which you'll have to compare your pointer to. Note that it will not work for memory allocated in another thread, since it will have its own stack.
here it is, works for MSVC:
#define isheap(x, res) { \
void* vesp, *vebp; \
_asm {mov vesp, esp}; \
_asm {mov vebp, ebp}; \
res = !(x < vebp && x >= vesp); }
int si;
void func()
{
int i;
bool b1;
bool b2;
isheap(&i, b1);
isheap(&si, b2);
return;
}
it is a bit ugly, but works. Works only for local variables. If you pass stack pointer from calling function this macro will return true (means it is heap)
In mainstream operating systems, the stack grows from the top while the heap grows from the bottom. So you might heuristically check whether the address is beyond a large value, for some definition of "large." For example, the following works on my 64-bit Linux system:
#include <iostream>
bool isHeapPtr(const void* ptr) {
return reinterpret_cast<unsigned long long int>(ptr) < 0xffffffffull;
}
int main() {
int iStack = 35;
int *ptrStack = &iStack;
std::cout << isHeapPtr(ptrStack) << std::endl;
std::cout << isHeapPtr(new int(5)) << std::endl;
}
Note that is a crude heuristic that might be interesting to play with, but is not appropriate for production code.
First, why do you need to know this? What real problem are you trying to solve?
The only way I'm aware of to make this sort of determination would be to overload global operator new and operator delete. Then you can ask your memory manager if a pointer belongs to it (the heap) or not (stack or global data).
Even if you could determine whether a pointer was on one particular heap, or one particular stack, there can be multiple heaps and multiple stacks for one application.
Based on the reason for asking, it is extremely important for each container to have a strict policy on whether it "owns" pointers that it holds or not. After all, even if those pointers point to heap-allocated memory, some other piece of code might also have a copy of the same pointer. Each pointer should have one "owner" at a time, though ownership can be transferred. The owner is responsible for destructing.
On rare occasions, it is useful for a container to keep track of both owned and non-owned pointers - either using flags, or by storing them separately. Most of the time, though, it's simpler just to set a clear policy for any object that can hold pointers. For example, most smart pointers always own their container real pointers.
Of course smart pointers are significant here - if you want an ownership-tracking pointer, I'm sure you can find or write a smart pointer type to abstract that hassle away.
Despite loud claims to the contrary, it is clearly possible to do what you want, in a platform-dependent way. However just because something is possible, that does not automatically make it a good idea. A simple rule of stack==no delete, otherwise==delete is unlikely to work well.
A more common way is to say that if I allocated a buffer, then I have to delete it, If the program passes me a buffer, it is not my responsibility to delete it.
e.g.
class CSomething
{
public:
CSomething()
: m_pBuffer(new char[128])
, m_bDeleteBuffer(true)
{
}
CSomething(const char *pBuffer)
: m_pBuffer(pBuffer)
, m_bDeleteBuffer(false)
{
}
~CSomething()
{
if (m_bDeleteBuffer)
delete [] m_pBuffer;
}
private:
const char *m_pBuffer;
bool m_bDeleteBuffer;
};
You're trying to do it the hard way. Clarify your design so it's clear who "owns" data and let that code deal with its lifetime.
here is universal way to do it in windows using TIP:
bool isStack(void* x)
{
void* btn, *top;
_asm {
mov eax, FS:[0x08]
mov btn, eax
mov eax, FS:[0x04]
mov top, eax
}
return x < top && x > btn;
}
void func()
{
int i;
bool b1;
bool b2;
b1 = isStack(&i);
b2 = isStack(&si);
return;
}
The only way I know of doing this semi-reliably is if you can overload operator new for the type for which you need to do this. Unfortunately there are some major pitfalls there and I can't remember what they are.
I do know that one pitfall is that something can be on the heap without having been allocated directly. For example:
class A {
int data;
};
class B {
public:
A *giveMeAnA() { return &anA; }
int data;
A anA;
};
void foo()
{
B *b = new B;
A *a = b->giveMeAnA();
}
In the above code a in foo ends up with a pointer to an object on the heap that was not allocated with new. If your question is really "How do I know if I can call delete on this pointer." overloading operator new to do something tricky might help you answer that question. I still think that if you have to ask that question you've done something very wrong.
How could you not know if something is heap-allocated or not? You should design the software to have a single point of allocation.
Unless you're doing some truly exotic stuff in an embedded device or working deep in a custom kernel, I just don't see the need for it.
Look at this code (no error checking, for the sake of example):
class A
{
int *mysweetptr;
A()
{
mysweetptr = 0; //always 0 when unalloc'd
}
void doit()
{
if( ! mysweetptr)
{
mysweetptr = new int; //now has non-null value
}
}
void undoit()
{
if(mysweetptr)
{
delete mysweetptr;
mysweetptr = 0; //notice that we reset it to 0.
}
}
bool doihaveit()
{
if(mysweetptr)
return true;
else
return false;
}
~A()
{
undoit();
}
};
In particular, notice that I am using the null value to determine whether the pointer has been allocated or not, or if I need to delete it or not.
Your design should not rely on determining this information (as others have pointed out, it's not really possible). Instead, your class should explicitly define the ownership of pointers that it takes in its constructor or methods. If your class takes ownership of those pointers, then it is incorrect behavior to pass in a pointer to the stack or global, and you should delete it with the knowledge that incorrect client code may crash. If your class does not take ownership, it should not be deleting the pointer.
I'm working on a memory pool/memory allocator implementation and I am setting it up in a manor where only a special "Client" object type can draw from the pool.The client can either be constructed directly onto the pool, or it can use the pool for dynamic memory calls or it could in theory do both.
I would like to be able to overload operator new and operator delete in a way that would call my pools "alloc()" and "free()" functions in order to get the memory needed for the object to construct upon.
One of the main issues that I am having is getting my operator delete to be able to free up the memory by calling the pool->free() function I have written. I came up with a hack that fixes it by passing the pool into the constructor and having the destructor do the deallocation work. This is all fine and dandy until someone needs to inherit from this class and override the destructor for their own needs and then forgets to do the memory deallocations. Which is why i want to wrap it all up in the operators so the functionality is tucked away and inherited by default.
My Code Is on GitHub here: https://github.com/zyvitski/Pool
My class definition for the Client is as follows:
class Client
{
public:
Client();
Client(Pool* pool);
~Client();
void* operator new(size_t size,Pool* pool);
void operator delete(void* memory);
Pool* m_pPool;
};
And the implementation is:
Client::Client()
{
}
Client::Client(Pool* pool)
{
m_pPool = pool;
}
Client::~Client()
{
void* p = (void*)this;
m_pPool->Free(&p);
m_pPool=nullptr;
}
void* Client::operator new(size_t size, Pool* pool)
{
if (pool!=nullptr) {
//use pool allocator
MemoryBlock** memory=nullptr;
memory = pool->Alloc(size);
return *memory;
}
else throw new std::bad_alloc;
}
void Client::operator delete(void* memory)
{
//should somehow free up the memory back to the pool
// the proper call will be:
//pool->free(memory);
//where memory is the address that the pool returned in operator new
}
Here is the example Main() that i'm using for the moment:
int main(int argc, const char * argv[]){
Pool* pool = new Pool();
Client* c = new(pool) Client(pool);
/*
I'm using a parameter within operator new to pass the pool in for use and i'm also passing the pool as a constructor parameter so i can free up the memory in the destructor
*/
delete c;
delete pool;
return 0;
}
So far my code works, but I want to know if there is a better way to achieve this?
Please let me know if anything I am asking/doing is simply impossible, bad practice or just simply dumb. I am on a MacBook Pro right now but i would like to keep my code cross platform if at all possible.
If you have any questions that would help you help me do let me know.
And of course, Thanks in advance to anyone who can help.
You might store additional information just before the returned memory address
#include <iostream>
#include <type_traits>
class Pool {
public:
static void* Alloc(std::size_t size) { return data; }
static void Dealloc(void*) {}
private:
static char data[1024];
};
char Pool::data[1024];
class Client
{
public:
void* operator new(size_t size, Pool& pool);
void operator delete(void* memory);
};
struct MemoryHeader {
Pool* pool;
};
void* Client::operator new(size_t size, Pool& pool)
{
auto header = static_cast<MemoryHeader*>(pool.Alloc(sizeof(MemoryHeader) + size));
std::cout << " New Header: " << header << '\n';
header->pool = &pool;
return header + 1;
}
void Client::operator delete(void* memory)
{
auto header = static_cast<MemoryHeader*>(memory) - 1;
std::cout << " Delete Header: " << header << '\n';
header->pool->Dealloc(header);
}
int main()
{
Pool pool;
Client* p = new(pool) Client;
std::cout << "Client Pointer: " << p << '\n';
delete p;
return 0;
}
With the help of Dieter Lücking I was able to figure out how to use my pool in operator new and operator delete
Here is the code for operator new:
void* ObjectBase::operator new(size_t size, Pool* pool)
{
if (pool!=nullptr) {
//use pool allocation
MemoryBlock** block = pool->Alloc(size+(sizeof(MemoryHeader)));
MemoryBlock* t = * block;
t = (MemoryBlock*)((unsigned char*)t+sizeof(MemoryHeader));
MemoryHeader* header = new(*block)MemoryHeader(pool);
header=nullptr;
return t;
}
else{
//use std allocation
void* temp = ::operator new(size);
if (temp!=nullptr) {
return temp;
}
else throw new std::bad_alloc;
}
}
Here is the code for operator delete
void ObjectBase::operator delete(void* memory)
{
MemoryBlock* temp = (MemoryBlock*)((unsigned char*)memory-sizeof(MemoryHeader));
MemoryHeader* header = static_cast<MemoryHeader*>(temp);
if (header->pool!=nullptr) {
if (header->pool->Free((MemoryBlock**)&header));
else
{
::operator delete(memory);
}
}
else{
::operator delete(memory);
}
}
I'm using the "Memory Header" idea that was suggested.
The code is also set up in a way that defaults to using a standard memory allocation call if for some reason the pool fails.
Thanks Again for your help.
If your delete operator simply calls free, you custom allocator will not do e very good job. The idea of a custom allocator is that it will work with a predefined memory region which it will have control over: when it allocates memory it will be from it's memory region or pool and when the memory is freed, the allocator is 'informed' it can reuse that memory.
Now, if you use free, you just return the memory to the heap, not to your memory pool. The way this part is usually done is with the use of smart pointers - to keep track of what memory is available.
Any other mechanism will do as long as you can keep track of which addresses are in use and which are available.
Hope this helps
I have a class that is described that way :
class Foo {
int size;
int data[0];
public:
Foo(int _size, int* _data) : size(_size) {
for (int i = 0 ; i < size ; i++) {
data[i] = adapt(_data[i]);
}
}
// Other, uninteresting methods
}
I cannot change the design of that class.
How can I create an instance of that class ? Before calling the constructor, I have to make it reserve enough memory to store its data, so it has to be on the heap, not on the stack. I guess I want something like
Foo* place = static_cast<Foo*>(malloc(sizeof(int) + sizeof(int) * size));
*place = new Foo(size, data); // I mean : "use the memory allocated in place to do your stuff !"
But I can't find a way to make it work.
EDIT : as commentators have noticed, this is not a very good overall design (with non-standards tricks such as data[0]), alas this is a library I am forced to use...
You could malloc the memory for the object and then use a placement new to create the object in the previously allocated memory :
void* memory = malloc(sizeof(Foo) + sizeof(int) * size);
Foo* foo = new (memory) Foo(size, data);
Note that in order to destroy this object, you can't use delete. You would have to manually call the destructor and then use free on the memory allocated with malloc :
foo->~Foo();
free(memory); //or free(foo);
Also note that, as #Nikos C. and #GManNickG suggested, you can do the same in a more C++ way using ::operator new :
void* memory = ::operator new(sizeof(Foo) + sizeof(int) * size);
Foo* foo = new (memory) Foo(size, data);
...
foo->~Foo();
::operator delete(memory); //or ::operator delete(foo);
You have a library that does this thing but doesn't supply a factory function? For shame!
Anyway, while zakinster's method is right (I'd directly call operator new instead of newing an array of chars, though), it's also error-prone, so you should wrap it up.
struct raw_delete {
void operator ()(void* ptr) {
::operator delete(ptr);
}
};
template <typename T>
struct destroy_and_delete {
void operator ()(T* ptr) {
if (ptr) {
ptr->~T();
::operator delete(ptr);
}
}
};
template <typename T>
using dd_unique_ptr = std::unique_ptr<T, destroy_and_delete<T>>;
using FooUniquePtr = dd_unique_ptr<Foo>;
FooUniquePtr CreateFoo(int* data, int size) {
std::unique_ptr<void, raw_delete> memory{
::operator new(sizeof(Foo) + size * sizeof(int))
};
Foo* result = new (memory.get()) Foo(size, data);
memory.release();
return FooUniquePtr{result};
}
Yes, there's a bit of overhead here, but most of this stuff is reusable.
If you really want to be lazy simply use a std::vector<Foo>. It will use more space (I think 3 pointers instead of 1) but you get all the benefits of a container and really no downsides if you know it is never going to change in size.
Your objects will be movable given your definition so you can safely do the following to eliminate reallocation of the vector during initial fill...
auto initialFooValue = Foo(0, 0)
auto fooContainer = std::vector<Foo>(size, initialFooValue);
int i = 0;
for (auto& moveFoo : whereverYouAreFillingFrom)
{
fooContainer[i] = std::move(moveFoo);
++i;
}
Since std::vector is contiguous you can also just memcopy into it safely since your objects are trivially-copyable.
I think a good C++ solution is to get raw memory with new and then use placement new to embed your class into it.
getting raw memory works like this:
Foo *f = static_cast<Foo *>(operator new(sizeof(Foo));
constructing the object in received memory works like this:
new (f) Foo(size, data); // placement new
remember that this also means that you have to manually clean up the place.
f->~Foo(); // call the destructor
operator delete(f); // free the memory again
My personal opinion is, that it is bad to use malloc and free in newly written C++ code.
I have some code here that implements a dynamic memory pool. The pool starts off at size 0 and grows with each successive allocation. It is used to try and minimise the overhead of tons of allocations and de-allocations.
The call to malloc is NOT matched by a call to free. It seems to be relying on the application that uses it to not call enough new's in succession for the application to leak a significant amount of memory.
I did not write it, so this is my best guess.
My question are:
Is the absence of a call to free a bug or am I missing something to do with overloading the delete operator?
Is this implementation relying on the OS to clean up the small amount of memory that does leak at exit?
Thanks.
//Obj.h
class Obj
{
public:
Obj(){};
void* operator new(std::size_t size);
void operator delete(void* p);
private:
static std::vector<void*> pool_;
static std::size_t checked_in_;
static std::size_t checked_out_;
};
//Obj.cpp
std::vector<void*> Obj::pool_;
std::size_t Obj::checked_out_ = 0;
std::size_t Obj::checked_in_ = 0;
void* Obj::operator new(std::size_t size)
{
if (pool_.empty())
{
++checked_out_;
return malloc(size);
}
else
{
--checked_in_;
++checked_out_;
void* p = pool_.back();
pool_.pop_back();
return p;
}
}
void Obj::operator delete(void* p)
{
pool_.push_back(p);
if (pool_.size() % 10000 == 0)
{
std::cout<<"mem leak\n";
}
--checked_out_;
++checked_in_;
}
The missing 'free' means that you cannot embed this in some larger application, start it up, shut it down, and end up back where you started. This is fine if you control the entire application, and not fine if this code has to, in fact, be embeddable. To make that work, you would need some entrypoint that walks the vector calling free.
It never leaks in the conventional sense, since each malloc'ed chunk is stored in the vector by operator delete for re-use, and the operator delete complains if it sees too many items in the vector.
You're creating a memory pool. This pool implementation will grow as needed, but will never return memory to the OS. That's normally a bug, but not when creating your own method of allocating memory- as long as this pool exists for the life of your program. You'll leak when the program exits, but you can likely live with that. Basically you're overriding how new/malloc usually work and doing memory completely on your own.