473,836 Members | 1,558 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Heap Manager and new/delete overloading

Hello,
I'm trying to create a basic Heap manager and i have some question
about new/delete overloading.
The following code give me this output :
$./heap
registered : 0x804d098
0x804d008 _Delete unknown block
registered : 0x804d138
0x804d008 _Delete unknown block
0x804d098 _Delete ok
0x804d0a8 _Delete unknown block
0x804d138 _Delete ok
0x804d148 _Delete unknown block


Why is the HeapManager::_D elete called to delete objects that weren't
created using HeapManager::_N ew ?
The only reason I see is that these calls come from my BlocksMap
internals. Is it possible to differenciate delete used by the libstdc++
and delete used by the parts of my programs which are after the
overloading ?
Thanks for any advice :-)
Silver

------------------------------------------------
#include <map>
#include <vector>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <iostream>

using namespace std;

class HeapManager
{
public:
struct BlockDescriptor {
size_t size;
char filename[100];
int line;
};
static HeapManager* pSelf;
~HeapManager ();
void* _New (size_t size, const string& filename, int line);
void _Delete (void* addr);
private:
typedef map<void*, BlockDescriptor *> t_blocksMap;
t_blocksMap BlocksMap;
};

HeapManager::~H eapManager ()
{
vector<t_blocks Map::iterator> toErase;
t_blocksMap::it erator i;
for(i=BlocksMap .begin(); i!=BlocksMap.en d(); i++) {
cout << "leak : " << i->second->filename << ":" << i->second->line
<<endl;
free(i->second);
free(i->first);
toErase.push_ba ck(i);
}
for(unsigned int j =0; j<toErase.size( ); j++) {
BlocksMap.erase (toErase[j]);
}
}

void* HeapManager::_N ew(size_t size, const string& filename, int line)
{
if(size <= 0)
return 0;

BlockDescriptor * pDesc =
(BlockDescripto r*)malloc(sizeo f(BlockDescript or));
pDesc->size = size;
strncpy(pDesc->filename,filen ame.data(),99);
pDesc->filename[99] = '\0';
pDesc->line = line;
void* block = malloc(size);
BlocksMap.inser t(make_pair(blo ck,pDesc));
cout << "registered : " << block << endl;
return block;
}

void HeapManager::_D elete(void* addr)
{
if(addr == 0)
return;
cout << addr << " ";
t_blocksMap::it erator i = BlocksMap.find( addr);
if (i != BlocksMap.end() ) {
cout << "_Delete ok " << endl;
free(i->second);
BlocksMap.erase (i);
} else {
cout << "_Delete unknown block" << endl;
}
free(addr);
}

void* operator new(size_t size, const string& filename, int line) {
return HeapManager::pS elf->_New(size, filename, line);
}

void* operator new[](size_t size, const string& filename, int line) {
return HeapManager::pS elf->_New(size, filename, line);
}

void operator delete (void* addr) {
HeapManager::pS elf->_Delete(addr );
}

void operator delete [] (void* addr) {
HeapManager::pS elf->_Delete(addr );
}

#define new new(__FILE__,__ LINE__)

HeapManager* HeapManager::pS elf = NULL;
HeapManager theHeap;

class Foo
{
public:
int bar;
};

int main()
{
HeapManager::pS elf = &theHeap;
Foo* ptr = new Foo;
Foo* ptr2 = new Foo;
delete ptr;
delete ptr2;
return 0;

}

Dec 20 '05 #1
3 4661
si*******@gmail .com wrote:
Hello,
I'm trying to create a basic Heap manager and i have some question
about new/delete overloading.
The following code give me this output :
$./heap
registered : 0x804d098
0x804d008 _Delete unknown block
registered : 0x804d138
0x804d008 _Delete unknown block
0x804d098 _Delete ok
0x804d0a8 _Delete unknown block
0x804d138 _Delete ok
0x804d148 _Delete unknown block


Why is the HeapManager::_D elete called to delete objects that weren't
created using HeapManager::_N ew ?
The only reason I see is that these calls come from my BlocksMap
internals. Is it possible to differenciate delete used by the libstdc++
and delete used by the parts of my programs which are after the
overloading ?
Thanks for any advice :-)
Silver

------------------------------------------------
#include <map>
#include <vector>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <iostream>

using namespace std;

class HeapManager
{
public:
struct BlockDescriptor {
size_t size;
char filename[100];
int line;
};
static HeapManager* pSelf;
~HeapManager ();
void* _New (size_t size, const string& filename, int line);
void _Delete (void* addr);
private:
typedef map<void*, BlockDescriptor *> t_blocksMap;
t_blocksMap BlocksMap;
};

HeapManager::~H eapManager ()
{
vector<t_blocks Map::iterator> toErase;
t_blocksMap::it erator i;
for(i=BlocksMap .begin(); i!=BlocksMap.en d(); i++) {
cout << "leak : " << i->second->filename << ":" << i->second->line
<<endl;
free(i->second);
free(i->first);
toErase.push_ba ck(i);
}
for(unsigned int j =0; j<toErase.size( ); j++) {
BlocksMap.erase (toErase[j]);
}
}

void* HeapManager::_N ew(size_t size, const string& filename, int line)
{
if(size <= 0)
return 0;

BlockDescriptor * pDesc =
(BlockDescripto r*)malloc(sizeo f(BlockDescript or));
pDesc->size = size;
strncpy(pDesc->filename,filen ame.data(),99);
pDesc->filename[99] = '\0';
pDesc->line = line;
void* block = malloc(size);
BlocksMap.inser t(make_pair(blo ck,pDesc));
cout << "registered : " << block << endl;
return block;
}

void HeapManager::_D elete(void* addr)
{
if(addr == 0)
return;
cout << addr << " ";
t_blocksMap::it erator i = BlocksMap.find( addr);
if (i != BlocksMap.end() ) {
cout << "_Delete ok " << endl;
free(i->second);
BlocksMap.erase (i);
} else {
cout << "_Delete unknown block" << endl;
}
free(addr);
}

void* operator new(size_t size, const string& filename, int line) {
return HeapManager::pS elf->_New(size, filename, line);
}

void* operator new[](size_t size, const string& filename, int line) {
return HeapManager::pS elf->_New(size, filename, line);
}

void operator delete (void* addr) {
HeapManager::pS elf->_Delete(addr );
}

void operator delete [] (void* addr) {
HeapManager::pS elf->_Delete(addr );
}

#define new new(__FILE__,__ LINE__)

HeapManager* HeapManager::pS elf = NULL;
HeapManager theHeap;

class Foo
{
public:
int bar;
};

int main()
{
HeapManager::pS elf = &theHeap;
Foo* ptr = new Foo;
Foo* ptr2 = new Foo;
delete ptr;
delete ptr2;
return 0;

}


First of all, symbols such as _New and _Delete are illegitimate. All
symbols beginning with an underscore and captial letter are reserved
for use by the implementation. Fix that, try it again to make sure it's
not an implementation conflict, and then we can talk.

Second, you might be interested in this FAQ that discusses overloading
new and delete:

http://www.parashift.com/c++-faq-lit...html#faq-11.14

Third, you might consider using the singleton pattern for your heap
manager rather than that pointer to self trick. See _Modern C++ Design_
chapter 6 for more than you ever wanted to know about C++ singletons.

Cheers! --M

Dec 20 '05 #2
Thanks for your answers.
From what i learnt from the FAQ, if i want that only the objects

created through my new(size_t, const string&, int) call my overloaded
delete, i must redefine delete(void*, const string& , int ).

I rewrote my code with Singleton and correct symbols, but if i redefine
delete(void*, const string&, int), the program crash in dbgheap.c:1252
(_CrtIsValidHea pPointer). If i comment my 'new' delete an keep the old
delete(void*), i get the same output than in the first message.

Silver

----------------
// heap.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <vector>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <iostream>

using namespace std;

class HeapManager
{
public:
struct BlockDescriptor {
size_t size;
char filename[100];
int line;
};
static HeapManager* Instance();

void* myNew (size_t size, const string& filename, int line);
void myDelete (void* addr);
private:
typedef map<void*, BlockDescriptor *> t_blocksMap;
t_blocksMap BlocksMap;
HeapManager();
HeapManager(con st HeapManager&);
HeapManager& operator= (const HeapManager&);
~HeapManager ();
};

HeapManager::He apManager()
{

}

HeapManager::He apManager(const HeapManager&)
{

}

HeapManager& HeapManager::op erator = (const HeapManager&)
{
return *Instance();
}

HeapManager* HeapManager::In stance()
{
static HeapManager inst;
return &inst;
}

HeapManager::~H eapManager ()
{
vector<t_blocks Map::iterator> toErase;
t_blocksMap::it erator i;
for(i=BlocksMap .begin(); i!=BlocksMap.en d(); i++) {
cout << "leak : " << i->second->filename << ":" << i->second->line
<<endl;
free(i->second);
free(i->first);
toErase.push_ba ck(i);
}
for(unsigned int j =0; j<toErase.size( ); j++) {
BlocksMap.erase (toErase[j]);
}
}

void* HeapManager::my New(size_t size, const string& filename, int line)
{
if(size <= 0)
return 0;

BlockDescriptor * pDesc =
(BlockDescripto r*)malloc(sizeo f(BlockDescript or));
pDesc->size = size;
strncpy(pDesc->filename,filen ame.data(),99);
pDesc->filename[99] = '\0';
pDesc->line = line;
void* block = malloc(size);
BlocksMap.inser t(make_pair(blo ck,pDesc));
cout << "registered : " << block << endl;
return block;
}

void HeapManager::my Delete(void* addr)
{
if(addr == 0)
return;
cout << addr << " ";
t_blocksMap::it erator i = BlocksMap.find( addr);
if (i != BlocksMap.end() ) {
cout << "_Delete ok " << endl;
free(i->second);
BlocksMap.erase (i);
} else {
cout << "_Delete unregistered" << endl;
}
free(addr);
}

void* operator new(size_t size, const string& filename, int line) {
return HeapManager::In stance()->myNew(size, filename, line);
}

void* operator new[](size_t size, const string& filename, int line) {
return HeapManager::In stance()->myNew(size, filename, line);
}

void operator delete(void* addr, const string& filename, int line) {
HeapManager::In stance()->myDelete(addr) ;
}

void operator delete[](void* addr, const string& filename, int line){
HeapManager::In stance()->myDelete(addr) ;
}
/*
void operator delete (void* addr) {
HeapManager::In stance()->myDelete(addr) ;
}

void operator delete [] (void* addr) {
HeapManager::In stance()->myDelete(addr) ;
}*/

#define new new(__FILE__,__ LINE__)

class Foo
{
public:
int bar;
};

int main()
{
Foo* ptr = new Foo;
Foo* ptr2 = new Foo;
delete ptr;
delete ptr2;
return 0;

}

Dec 21 '05 #3
si*******@gmail .com wrote:
Thanks for your answers.
From what i learnt from the FAQ, if i want that only the objects created through my new(size_t, const string&, int) call my overloaded
delete, i must redefine delete(void*, const string& , int ).


Yes, you must do this for exception safety. See the FAQ.

I rewrote my code with Singleton and correct symbols, but if i redefine
delete(void*, const string&, int), the program crash in dbgheap.c:1252
(_CrtIsValidHea pPointer). If i comment my 'new' delete an keep the old
delete(void*), i get the same output than in the first message.
You must not do this. See below.

Silver

----------------
// heap.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <vector>
#include <stdlib.h>
Prefer <cstdlib>
#include <string>
#include <string.h>
Prefer <cstring>
#include <iostream>

using namespace std;

class HeapManager
{
public:
struct BlockDescriptor {
size_t size;
char filename[100];
int line;
};
static HeapManager* Instance();

void* myNew (size_t size, const string& filename, int line);
void myDelete (void* addr);
private:
typedef map<void*, BlockDescriptor *> t_blocksMap;
t_blocksMap BlocksMap;
HeapManager();
HeapManager(con st HeapManager&);
HeapManager& operator= (const HeapManager&);
~HeapManager ();
};

HeapManager::He apManager()
{

}

HeapManager::He apManager(const HeapManager&)
{

}

HeapManager& HeapManager::op erator = (const HeapManager&)
{
return *Instance();
}

HeapManager* HeapManager::In stance()
{
static HeapManager inst;
return &inst;
}

HeapManager::~H eapManager ()
{
vector<t_blocks Map::iterator> toErase;
t_blocksMap::it erator i;
for(i=BlocksMap .begin(); i!=BlocksMap.en d(); i++) {
cout << "leak : " << i->second->filename << ":" << i->second->line
<<endl;
free(i->second);
free(i->first);
toErase.push_ba ck(i);
}
for(unsigned int j =0; j<toErase.size( ); j++) {
BlocksMap.erase (toErase[j]);
}
}

void* HeapManager::my New(size_t size, const string& filename, int line)
{
if(size <= 0)
return 0;

BlockDescriptor * pDesc =
(BlockDescripto r*)malloc(sizeo f(BlockDescript or));
pDesc->size = size;
strncpy(pDesc->filename,filen ame.data(),99);
pDesc->filename[99] = '\0';
pDesc->line = line;
void* block = malloc(size);
BlocksMap.inser t(make_pair(blo ck,pDesc));
cout << "registered : " << block << endl;
return block;
}

void HeapManager::my Delete(void* addr)
{
if(addr == 0)
return;
cout << addr << " ";
t_blocksMap::it erator i = BlocksMap.find( addr);
if (i != BlocksMap.end() ) {
cout << "_Delete ok " << endl;
free(i->second);
BlocksMap.erase (i);
} else {
cout << "_Delete unregistered" << endl;
}
free(addr);
}

void* operator new(size_t size, const string& filename, int line) {
return HeapManager::In stance()->myNew(size, filename, line);
}

void* operator new[](size_t size, const string& filename, int line) {
return HeapManager::In stance()->myNew(size, filename, line);
}

void operator delete(void* addr, const string& filename, int line) {
HeapManager::In stance()->myDelete(addr) ;
}

void operator delete[](void* addr, const string& filename, int line){
HeapManager::In stance()->myDelete(addr) ;
}
/*
void operator delete (void* addr) {
HeapManager::In stance()->myDelete(addr) ;
}

void operator delete [] (void* addr) {
HeapManager::In stance()->myDelete(addr) ;
}*/

#define new new(__FILE__,__ LINE__)
Get rid of this macro. See below.

class Foo
{
public:
int bar;
};

int main()
{
Foo* ptr = new Foo;
Foo* ptr2 = new Foo;
delete ptr;
delete ptr2;
return 0;

}


First, regarding the singleton, I'd suggest something along these
lines, though perhaps you need something even more sophisticated in
terms of lifetime management (for which, see _Modern C++ Design_):

template<class T>
class Singleton
{
public:
static T& Instance();
private:
// Disabled functions
Singleton();
Singleton( const Singleton& );
Singleton& operator=( const Singleton& );
Singleton* operator&();
~Singleton();
};

template<class T>
T& Singleton<T>::I nstance()
{
static T myObject;
return myObject;
}
class HeapManager
{
// Private ctor/dtor accessible only to friends
friend class Singleton<HeapM anager>;
HeapManager() { /* ... */ }
~HeapManager() { /* ... */ }

// Disabled functions for singleton usage
HeapManager( const HeapManager& );
HeapManager& operator=( const HeapManager& );
HeapManager* operator&();

// ...

public:
// ...
};

typedef Singleton<HeapM anager> theHeapManager;

Second, regarding the questions from your previous post:
registered : 0x804d098
0x804d008 _Delete unknown block
registered : 0x804d138
0x804d008 _Delete unknown block
0x804d098 _Delete ok
0x804d0a8 _Delete unknown block
0x804d138 _Delete ok
0x804d148 _Delete unknown block


Why is the HeapManager::_D elete called to delete objects that weren't
created using HeapManager::_N ew ?


Because in your original code you overload the *global* new and delete
operators. Consequently, your delete operator is being called from
std::string, but your new operator wasn't called from std::string
because the function signatures didn't match and your "#define new"
wasn't in effect yet.

In your updated code, you (rightly) provide a matching delete operator
for your new operator, but you incorrectly invoke the global (i.e., not
your own) delete operator in main(). Also, your updated code won't work
since the file and line numbers must be identical to match your map's
key. With your current operators, you'd need to do something like this
(assuming you get rid of the macro):

Foo* ptr = new("Bob",1) Foo;
Foo* ptr2 = new("Joe",2) Foo;
operator delete(ptr, "Bob",1); // same parameters as above!
operator delete(ptr2, "Joe",2); // same parameters as above!

You'll probably want to change to some other key type than a string/int
pair since the filename/line number thing won't work. In order to get
rid of the ugly syntax in this code, I'll refer you to that same FAQ
again. It describes in detail how to create a custom new/delete pair
and then how to overload the gloabal new/delete operators to use them.

http://www.parashift.com/c++-faq-lit...html#faq-11.14

If you don't understand the FAQ, ask some specific questions. I'm sure
someone here can help.

Cheers! --M

Dec 21 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
5253
by: | last post by:
Hi all, I've been using C++ for quite a while now and I've come to the point where I need to overload new and delete inorder to track memory and probably some profiling stuff too. I know that discussions of new and delete is a pretty damn involved process but I'll try to stick to the main information I'm looking for currently. I've searched around for about the last too weeks and have read up on new and overloading it to some extent but...
17
5055
by: Jonas Rundberg | last post by:
Hi I just started with c++ and I'm a little bit confused where stuff go... Assume we have a class: class test { private: int arr; };
9
2172
by: swengtoo | last post by:
My understanding is that an auto_ptr can never own an object that was created on the stack. This is because when auto_ptr goes out of scope, it calls 'delete' for the object it points to. Is my understanding correct? Or did I miss anything here? Thanks!
37
2799
by: yogpjosh | last post by:
Hello All, I was asked a question in an interview.. Its related to dynamically allocated and deallocated memory. eg. //start char * p = new char; ...
3
3472
by: toton | last post by:
Operator overloading has a sort syntax rather than member function call for stack based memory allocation. like complex<int> c1,c2,c3; c3= c1+c2; How the same can be applied to heap based memory allocation? like complex<int> * c1,*c2,*c3; i still want to do something like c3 = c1+c2 ; rether than *c3 = *c1+*c2;
13
7279
by: Karthik | last post by:
In a recent techincal interview on C++, I came across this strange question.... How to ensure that your class object is always created in heap (by a new operator)? The compiler should throw error, if the object is created in stack. Note:- Dont hide the construtor. Is it possible?
16
4454
by: sarathy | last post by:
Hi all, I need a few clarifications regarding memory allocaion in C++. I apologize for the lengthy explanation. 1. In C++, Objects are allocated in heap. What does heap refer to? Is it an area in RAM/Memory or does it refer to a data structure being used for storing objects. 2. In C++, functions and its local variables go in stack. If local variables that are primitives go in stack, it is OK. But what
4
14779
by: Justin | last post by:
Recieved the message: SQL0954C Not enough storage is available in the application heap to process the statement. SQLSTATE=57011 After viewing other posts, they recommended changing the applheapsz (which was completed). We have restarted DB2. The query is not too complex. The interesting point is that we ran the query yesterday with no issues. The server we are testing is a new box in which multiple "break DB2" queries were...
5
24871
by: kumarmdb2 | last post by:
Hi guys, For last few days we are getting out of private memory error. We have a development environment. We tried to figure out the problem but we believe that it might be related to the OS (I am new to Windows so not sure). We are currently bouncing the instance to overcome this error. This generally happen at the end of business day only (So maybe memory might be getting used up?). We have already increased the statement heap & ...
0
9827
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9677
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10862
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10560
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10262
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7798
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6986
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5662
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
3
3119
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.