How to know object creation is on heap or not..? - c++

We want to work on low latency system, heap allocation is costlier in the application. but for some extent object creation on heap is allowed. Thats why we want indication whether object is created is on heap or not..?
Is the below methodology is the correct way to find out object created on heap memory..?
Will have generic class where new and delete operator is overloaded to maintain heap allocated pointers....
#include <iostream>
#include <set>
using namespace std;
class MemStat //base class
{
typedef set<MemStat*> POINTERS;
static POINTERS m_ptrlist;
public:
void* operator new (size_t size)
{
MemStat* ptr = ::new MemStat;
m_ptrlist.insert(ptr);
return ptr;
}
void operator delete(void* dptr)
{
MemStat* ptr = static_cast<MemStat*>(dptr);
m_ptrlist.erase(ptr);
::delete ptr;
}
// void* operator new[] (size_t sz);
// void operator delete[] (void*);
bool is_on_heap() { m_ptrlist.find(this) != m_ptrlist.end(); }
protected: // ctor & dtor are protected for restrictions
MemStat() { }
virtual ~MemStat() { }
MemStat(const MemStat&) { }
const MemStat& operator=(const MemStat& ) { return *this; }
};
MemStat::POINTERS MemStat::m_ptrlist;
for the end user classes which we need to check for the heap creation will be derived from MemStat class uses new & delete operator call while instantiating base class object.
class MyClass : public MemStat //end user class
{
};
int main()
{
MyClass* myptr = new MyClass;
MyClass obj;
cout << myptr->is_on_heap() << endl; //results into yes
cout << obj.is_on_heap() << endl; //reults into no
delete myptr;
}

Note that your scheme fails miserably as soon as a MyClass object is a sub-object (inherited or contained) of another object which might or might not by allocated dynamically. (And the tricks I know for preventing dynamic allocation fail on that one as well.)
So what you're doing just further slows down heap allocation without gaining much. Except for a few very rare circumstances, where an object is allocated is something your class' users decide.
If they think they need to dynamically allocate one, who are you to disagree?

Related

combine allocation/construction Or deallocation/destruction with custom raw memory provision

I need to provide a utility function where both memory allocation and object construction take place and the user gets the pointer in return. Similarly, there is a need to provide a utility function for deallocation and destruction also.
Here is what I implemented: (I have not implemented for array type though)
#include <cstdlib> // for malloc
#include <iostream> // for cout
#include <string> // for memset
// C++ class with some initial state x = 10
class SomeClass {
public:
SomeClass() : x(10) {}
int x = 0;
};
template<typename T, typename ... Args>
inline T* MY_MODULE_NEW(Args&&... args) {
// some custom allocator logic here which allocates just raw memory
// for example purpose just use malloc
void *p = malloc(sizeof(T));
memset(p,0,sizeof(T));
T* t = new(p) T(std::forward<Args>(args)...);
return t;
}
template<typename T>
inline void MY_MODULE_DELETE(T* ptr) {
ptr->~T();
// some custom allocator logic here, which deallocates raw memory
// for example purpose just use free
free(ptr);
}
int main() {
SomeClass* sc = MY_MODULE_NEW<SomeClass>();
std::cout << sc->x << std::endl;
SomeClass* sc2 = MY_MODULE_NEW<SomeClass>(*sc);
std::cout << sc2->x << std::endl;
MY_MODULE_DELETE(sc);
MY_MODULE_DELETE(sc2);
}
I have the following concerns:
From the performance point of view, Is this inline function good enough? Can we do better?
Personally I feel MY_MODULE_NEW<SomeClass>(...) syntax is almost similar to the canonical syntax for operator new which is new SomeClass(). Is there any other idiomatic way to achieve the same result?
Thank You!

What is the proper way to pass raw pointers from a larger object to a smaller object to do something specialized with?

I'm using a C library from C++ and consequently I'm dealing with a lot of raw pointers. I want to create a pointer in an object (like A) and then pass the pointer to another object (like B) for doing something specialized with. I then want B's life to end but A to persist to do other things with the pointer.
The following code produces a double free or corruption error and then exits with code 139. When I remove the destructors, however, this does not happen (which doesn't make a whole lot of sense to me since I thought any object that uses raw pointers should implement its own destructor for tidying up after itself).
Why does this happen and is there a better strategy for achieving the above?
#include <iostream>
#include <sstream>
using namespace std;
struct World { // potentially containing a large amount of data
int a;
int b;
const char *c;
};
class B {
private:
World *world_;
public:
std::string doSomethingCleverWithWorld(){
std::ostringstream os;
os << world_->c << " = " << world_->a + world_->b <<std::endl;
return os.str();
}
explicit B(World *world) {
world_ = world;
}
~B(){
// I want the pointer to world_ to persist after use of B
// delete world_;
}
};
class A {
private:
World *world_;
public:
explicit A(World *world) {
world_ = world;
}
~A() {
delete world_;
}
A(const A &a) {
this->world_ = a.world_;
}
A(A &&a) noexcept {
this->world_ = a.world_;
}
A &operator=(const A &a) {
if (this != &a) {
this->world_ = a.world_;
}
return *this;
}
A &operator=(A &&a) noexcept {
if (this != &a) {
this->world_ = a.world_;
}
return *this;
}
std::string doCleverStuff(){
B b(world_);
return b.doSomethingCleverWithWorld();
}
};
int main() {
World world{
4, 6, "stuff"
};
A a(&world);
std::string clever = a.doCleverStuff();
std::cout << clever << std::endl;
return 0;
};
Output
stuff = 10
double free or corruption (out)
Process finished with exit code 134
Just to wrap all the comments - data can be allocated on the heap and on the stack. Allocations on the heap are done using new and freed using delete (or malloc() and free() in C; delete will call destructor and free memory and free will simply free memory).
When you create local variable (and your World instance is local to main() function) your data will be created on the stack and will live till the end of the scope it was created in - which in your case is scope of the function main(). You can manage only memory allocated dynamically (on the heap) and attempts to do so with memory allocated on the stack will lead to issue you've encountered.

why overloaded new operator is calling constructor even I am using malloc inside overloading function?

I am trying to understand overloading new operator. I wrote the code as below.
#include <iostream>
#include <cstdlib>
#include <new>
using namespace std;
class loc
{
int lo, la;
public:
loc()
{
}
loc(int x, int y)
{
cout << "In constructor\n";
lo = x;
la = y;
}
void show()
{
cout << lo << " ";
cout << la << endl;
}
void *operator new(size_t sz);
void operator delete(void *p);
};
void *loc::operator new(size_t sz)
{
cout << "in Overloaded new\n";
void *p = malloc(sz);
return p;
}
void loc::operator delete(void *p)
{
cout << "in Overloaded delete\n";
free(p);
}
int main()
{
loc *p1 = new loc(10, 20);
p1->show();
delete p1;
return 0;
}
I thought it won't call the constructor because I overloaded the new operator with malloc function call inside overloading function. But the output is as below.
in Overloaded new
In constructor
10 20
in Overloaded delete
That means constructor is getting called. How this is possible? Does this mean will malloc() call constructor?
A new expression results in two separate things happening: allocation of the memory needed by the object begin created, and initialization of the object.
The new operator, on the other hand, just handles the allocation part. When you overload the new operator with respect to a specific class, you are replacing the allocation of memory to the object.
This division of functions makes sense when you realize that not all objects are allocated on the heap. Consider the following case:
int main() {
string someString;
..
}
The local variable is not dynamically allocated; new is not used; however the object still needs to be initialized so the constructor is still called. Note that you did not need to explicitly call the constructor - it is implicit in the language that an appropriate constructor will always be called to initialize an object when it is created.
When you write a 'new expression', the compiler knows to emit instructions to invoke the new operator (to allocate memory as needed) and then to call the constructor (to initialize the object). This happens whether or not you overload the new operator.

how placement new works in c++? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++'s “placement new”
I just learned about the placement new operator and tried creating my own memory manager.
Here is the code of my template base class for Memory
#ifndef _MEMORY_BASE_H_
#define _MEMORY_BASE_H_
//=========================================!
#include <new>
#include <exception>
#include <iostream>
//=========================================!
using namespace std;
//=========================================!
template <typename T>
class Memory_Base
{
public :
//standard new
void* operator new(size_t T);
// placement new
void* operator new(size_t T,void* pAddress);
//standard delete
void operator delete(void* pAny);
};
//=========================================!
// Implementation
//=========================================!
template <typename T>
void* Memory_Base<T>::operator new(size_t T)
{
cout << "Memory_Base<T>:: new called" << endl;
void* pTemp = malloc(sizeof(T));
if(!pTemp)
throw bad_alloc();
else
return pTemp;
}
//=========================================!
template <typename T>
void* Memory_Base<T>::operator new(size_t T,void* pAddress)
{
cout << "Memory_Base<T>:: placement new called" << endl;
return pAddress;
}
//=========================================!
template <typename T>
void Memory_Base<T>::operator delete(void* pAny)
{
cout << "Memory_Base<T>:: delete called" << endl;
free(pAny);
}
//=========================================!
#endif
Now, i inherited myclass from above class,in another header file , something like as below
#ifndef _MY_CLASS_H_
#define _MY_CLASS_H_
//=========================!
#include "Memory_Base.h"
//=========================!
class MyClass :public Memory_Base<MyClass>
{
private :
int ma;
public :
MyClass():ma(-1){}
~MyClass(){}
};
//============================!
#endif
Now, in my main, i am trying to create objects of myclass in the following manner
//============================!
#include "MyClass.h"
//============================!
int main()
{
// This is how new for MyClass is called
MyClass* pMyClass = new MyClass();
// This is how placement new for MyClass is called
MyClass obj[10];
MyClass* pMyClass1 = new(&obj)MyClass();
return 0;
}
//============================!
Questions ::
1. When i run main, the base address of obj and pMyClass1 were the same, as expected. However, i am just returning the pointer pAddress, then how the placement new works ?
my obj[10], is in stack, but, the destructor is not getting called.
Any ideas ?
Atul
P.S :: I have to implement the new[] and delete[] in Memory_Base.
MyClass obj[10];
Allocates and creates 10 objects of the type MyClass on the local storage.
Further,
MyClass* pMyClass1 = new(&obj)MyClass();
Just calls the constructor MyClass::MyClass(). The this pointer in the MyClass constructor will be equal to &obj. The returned pointer pMyClass1 will therefore be equal to &obj.
Also, In case of placement new it is your responsibility to destroy the placed object by explicitly calling the destructor, the placed objects destructor wont be called implcitly.
Since, the array of objects since placed on stack will be deallocated once the program returns in your case.

Properly Overloading new/delete new[]/delete[]

This is a follow up to my previous question,
Initializing a class using malloc
Accepted answer on the question works and gives me new/delete on the avr-gcc, here is the problem but my overloaded new delete wracks havoc on regular gcc, what is the proper way to overload new delete all my classes derive from a common base class so ideally i would like to just override new delete for my object so it does not mess with stl stdlib etc.
'new' and 'delete' can overloaded inside the common Object base class. So, that will be applicable only to that hierarchy.
class Object {
public:
void* operator new (size_t size);
void operator delete (void *p);
};
class Derived : public Object {
// uses the above versions of new/delete
};
[Note: It's an added advantage for you as all your class are getting derived from a common Object class (as mentioned in your question and the link)]
Overload the new & delete inside your own class & not Globally.
For eg: If name of your common class is YourClass, You can overload them as follows:
void *YourClass::operator new(size_t size)
{
void *p;
cout << "In overloaded new.";
p = malloc(size);
if(!p)
{
throw std::bad_alloc; //Throw directly than with named temp variable
}
return p;
}
void YourClass::operator delete(void *p)
{
cout << "In overloaded delete.\n";
free(p);
}
void *YourClass::operator new[](size_t size)
{
void *p;
cout << "Using overload new[].\n";
p = malloc(size);
if(!p)
{
throw std::bad_alloc;
}
return p;
}
void YourClass::operator delete[](void *p)
{
cout << "Free array using overloaded delete[]\n";
free(p);
}
All classes derived from YourClass will be able to use these overloaded new and delete operators.