flat assembler
Message board for the users of flat assembler.

Index > High Level Languages > overloading new and delete(c++)

Author
Thread Post new topic Reply to topic
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 21 May 2013, 21:37
does anybody have experience with this? i think i cant figure out when delete is called exactly. sometimes it seems to be called automatically on class variables. for example my class has an "int temp" and when i delete the ptr to my object of this class. it seems to call delete on the variable temp?? i had some weird errors "deleting scalar ..." and stuff.

does anyone know exactly what news and deletes there are, and when they are called?
and there is a new(size_t,int,const char*,int). what should this one do??

_________________
--for science
Post 21 May 2013, 21:37
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4352
Location: Now
edfed 22 May 2013, 08:21
delete is the ~destructor
new is the constructor.

class thing {
int myint; //this int is created inside the instance of thing
thing() {} //called with new.
~thing() {} //called with delete. myint will be deleted automatically when calling the destructor
};

of course, you can create instances of a class without the new, it is like when you create an int in your code, in fact, it will be in the stack, and then, deleted automatically at the end of the current function body.

all this is managed by the c++ run time lib.

do you get it?

some lib with recursive objects manage delete at the top level, deleting all sub object in one pass when deleting the root, like many xml libs.
Post 22 May 2013, 08:21
View user's profile Send private message Visit poster's website Reply with quote
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 22 May 2013, 08:57
... i know what new and delete do
but im talking about the internal memory allocation.

void* operator new(size_t size)
{
return malloc(size);
}

would be an example.
but what i dont know, when exactly are news and deletes called.
it seems that they are sometimes called automatically
Post 22 May 2013, 08:57
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4352
Location: Now
edfed 22 May 2013, 09:20
Post 22 May 2013, 09:20
View user's profile Send private message Visit poster's website Reply with quote
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 22 May 2013, 10:11
this is not what i mean
automatically called = not me
for example i exit a block and the delete is automatically called on objects on the stack (or something like that)
Post 22 May 2013, 10:11
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1659
Location: Toronto, Canada
AsmGuru62 22 May 2013, 10:31
I have only overriden a simple form of new/delete.
Like these ones:
Code:
// -----------------------------------------------------------------------------
PVOID operator new (UINT nBytes)
{
        return HeapAlloc (glb.m_HObjectAllocator, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, nBytes);
}

// -----------------------------------------------------------------------------
VOID operator delete (PVOID p)
{
        HeapFree (glb.m_HObjectAllocator, HEAP_NO_SERIALIZE, p);
}
    

They are usually called when creating/deleting pointers to class instances.
They will be called automatically when:

1. Instance is declared on stack and the declaration scope ends
2. Instance is declared globally (or static in the file) and program ends
3. Instance is declared as a class member and class created/destroyed

^^^ All these cases are NOT about the pointers to instances, but full instances, like "int a;".

The 'new' prototype you describe in post #1 is most likely the custom defined 'new' (MFC likes to do this) and is was done for tracking memory allocations.
Last two parameters (char* and int) are most likely the file name and line number where allocation happens.
Usually this kind of 'new' is called with a macro defined differently for DEBUG and RELEASE:
Code:
#ifdef _DEBUG
#define NEW(len)    new (len, __FILE__, __LINE__)
#else
#define NEW(len)    new (len)
#endif
    
Post 22 May 2013, 10:31
View user's profile Send private message Send e-mail Reply with quote
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 23 May 2013, 06:42
okay thanks, that was what i wanted to know.
so for a foolproof memorymanagement i would have to write my own compiler Razz
Post 23 May 2013, 06:42
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1659
Location: Toronto, Canada
AsmGuru62 23 May 2013, 10:59
Smile
I would not go that far.
Here is my model of C++ coding (of course -- just my opinion):

1. Overload the new/delete by allocating memory from a private heap with HEAP_ZERO_MEMORY flag.
This way, when constructor of any class is called -- all members of the class are set to NULL or zero, so you do not
need to write all these lines in constructor.

2. Who said pointers are bad?!
Never use instances of a class declared inside of other classes.
Always use pointers for that and always 'new' them in constructor and 'delete' in destructor.

- reason A) when using full instance of class 1 in a header file (I assume you put your classes in .H files) for class 2,
you need to include the full include file for that class 1 into .H for class 2.
These dependencies soon (when project grows) will make it hard to include
your class .H files where you need them (.CPP files).
Use forward references instead.

- reason B) when instructions to access memory are encoded - it requires 1 byte offset to access a location 127 bytes or less
and 4 bytes (32 bit code) - if > 127 bytes. When declaring a lot of instances in a class - the class data
grows beyond 127 bytes in a quick way and the code is bloated.

3. Create a base class which encapsulates a private heap.
In constructor call HeapCreate() and in destructor -- HeapDestroy().
Derive all your memory 'hungry' classes from that class, so you do not
need to free small blocks left from large memory structure -- just one
HeapDestroy() in destructor will remove them in one shot.

4. Always end your threads by returning from thread procedure -- this way if
any memory was allocated by a thread -- allocator class will simply exit scope and there will be no leaks.

5. Provide a couple of classes to just allocate some memory: make a class which does
VirtualAlloc/VirtualFree for large blocks and the one with malloc/free for a small blocks in some scope.
Post 23 May 2013, 10:59
View user's profile Send private message Send e-mail Reply with quote
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 23 May 2013, 21:24
well i think you may know languages like c# or *shudders* java.
if you make a
myclass* bla = newRef(othermyclassptr);
it should add 1 to the ref counter
if i then delete bla, i want to decrement the counter until its zero and then delete the object.
so i wether have a list for each and every pointer (no way) or i put an int in front of every object (just allocate 4 bytes more and add 4 to the ptr and then return it.
the problem with that is, that i cant prevent that somebody does &intarray[5]
so he would have a reference on some int array, but no valid reference counter.
so another method would be, to make a wrapper class which holds the ref counter
template <T> class Reference;
and then i make mynewref = new Reference(&intarray[5]);
and continue to only work with that reference.
but that makes things so complicated, that i think its rubbish to do that.
who would code like this? its just painful.
=/ so i think i would have to make my own compiler which manages all this stuff.

my biggest problem now is this:
i have a method getting a char*
i can call it via method("hello there");
or i can call it via method(mycharptr);
so the problem when i dont delete the second one, and the caller forgets to delete too, i have a leak.
yeah its like a try to make c++ more foolproof Razz
Post 23 May 2013, 21:24
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1659
Location: Toronto, Canada
AsmGuru62 24 May 2013, 15:11
Create a class which encapsulates char* inside and it should solve the issue.
Always make a copy of char* in the class and this is it.
If you need a lot of copies of same text -- create a class for it and make a string pool
where you add a char* only if it is not yet there and if it is -- just put a reference to it into char* class.
It is all possible to make with no leaks, just with a proper architecture.
Post 24 May 2013, 15:11
View user's profile Send private message Send e-mail Reply with quote
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 24 May 2013, 15:13
but i want speed+proper architecture Razz i think both is not so easy to do
Post 24 May 2013, 15:13
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 24 May 2013, 17:35
The new/delete operators are only called when you explicitly do "c = new Class(...)" or "delete c" respectively. There are in fact two variants of each with with three different parameter options (though you only need to define the ones you use):

http://www.cplusplus.com/reference/new/operator%20delete/
http://www.cplusplus.com/reference/new/operator%20delete[]/
http://www.cplusplus.com/reference/new/operator%20new/
http://www.cplusplus.com/reference/new/operator%20new[]/

These operators don't explicitly call the constructors or destructors just allocate/free memory, as shown by AsmGuru62 already. The constructor/destructor are separate ("thiscall") calls made by the compiler on the memory location (the void * parameter). The two basic cases are heap allocated pointers and local references*:
Code:
{ // Scope
Class * a = new Class(); // operator new is called then a::Class constructor [heap]
Class b; // b::Class constructor called directly [stack]
// ...
} // Scope ends - b::~Class destructor called but a is not deleted/deconstructed (mem-leak!)    
*In the case of local classes-within-classes, the local reference is part of the parent class's heap allocation:
Code:
class A
{
public:
A() : b() { }
private:
B b;
}    
Doing "a = new A()" would call operator new once for the size of A (which includes the size of B and any other members) and then calls the constructor for A at memory location a; this then calls the constructor for B at memory location a.b.

Explaining this is probably harder than doing it Laughing Hope that helps Cool
Post 24 May 2013, 17:35
View user's profile Send private message Reply with quote
fredlllll



Joined: 17 Apr 2013
Posts: 56
fredlllll 02 Jun 2013, 21:20
i'll do my next try on this in a few days and post some results =3 thanks for your explanations.(i were ill the last week so it took me a bit to answer)
Post 02 Jun 2013, 21:20
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.