Active TopicsActive Topics  Display List of Forum MembersMemberlist  Search The ForumSearch  HelpHelp
  RegisterRegister  LoginLogin
Developers
 Brain Games Forums : Developers
Subject Topic: memory manager... Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
Popolon
Admin Group
Admin Group
Avatar

Joined: 05 November 2002
Location: Spain
Posts: 3135
Posted: 05 November 2003 at 11:15 | IP Logged Quote Popolon

Hi jpkokkon!

I've been using the "debug_memorymanager" that you sent me. However I've some doubts...

When I compile, I get this warning for each CPP file I compile:

c:\brain\mog2editor\actionscript.cpp(33) : warning C4291: 'void *__cdecl operator new(unsigned int,const char *,int)' : no matching operator delete found; memory will not be freed if initialization throws an exception
        c:\brain\mog2editor\debug_memorymanager.h(138) : see declaration of 'new'

Is this normal? The program compiles normally after this warning, and I can run it (well, some times an exception i thrown saying that "Mixed arrayed and normal versions of new/delete", but I'm starting to fix those...

It's just so strange that you get an error in this code:

char *v=new char[10];
delete v;

The memory manager wants you to write:

char *v=new char[10];
delete []v;




Back to Top View Popolon's Profile Search for other posts by Popolon Visit Popolon's Homepage Send Private Message Add to Buddy List
 
Popolon
Admin Group
Admin Group
Avatar

Joined: 05 November 2002
Location: Spain
Posts: 3135
Posted: 05 November 2003 at 11:22 | IP Logged Quote Popolon

Hey! The memorymanager is not working properly with my Visual C++ 6.0!!

I alloc memory for a class called BButton, and I get a pointer at 0x00e80180, then I use it, and when I try to free it, the memorymanager says to me that that BBurron has not been initialized. I've been looking through the generated code, and I've found an error in the ASSEMBLER code generated by the compiler!!! How can this be!!!!!!!

Look at the following code, and carefully at the line with an asterisk:

0047C2B5   mov        eax,dword ptr [ebp-4]
0047C2B8   push        eax
0047C2B9   call        `eh vector destructor iterator' (004dd320)
0047C2BE   mov        ecx,dword ptr [ebp+8]
0047C2C1   and        ecx,1
0047C2C4   test        ecx,ecx
0047C2C6   je          BButton::`vector deleting destructor'+57h (0047c2d7)
0047C2C8   mov        edx,dword ptr [ebp-4]
* 0047C2CB   sub        edx,4
0047C2CE   push        edx
0047C2CF   call        @ILT+6875(operator delete[]) (00402ae0)

It subs 4 to the pointer in EDX before calling the operator delete! This causes the delete operator to be called with 0x00e8017c instead of 0x00e80180 (I've stepped in the call using the debugger), and of course it desn't find any memory allocated on 0x00e8017c!!!

Have you experienced something like that?
Do you know who's the author of that code, there's no e-mail address in the readme.txt file so that I can ask whether I am doing something bad or not...

Looking at it with more care, I've found that this error happens just with deleting the classes defined by me, and not deleting char, int,... data.
Back to Top View Popolon's Profile Search for other posts by Popolon Visit Popolon's Homepage Send Private Message Add to Buddy List
 
jpkokkon
Newbie
Newbie


Joined: 09 October 2003
Location: Finland
Posts: 23
Posted: 05 November 2003 at 12:42 | IP Logged Quote jpkokkon

Hmm. Having problems, eh..

Well, first of all, writing:

char *v=new char[10];
delete v;

...Is is erroneous.

The memory manager wants you to write:

char *v=new char[10];
delete []v;

...Which is correct. Of course, you should delete an array with the array delete operator, not the plain delete operator.

Using wrong kind of delete operator seems to usually work just fine (or at least it does not crash), but as it may cause some problems (or at least it is not proper coding), you should not mix the delete and delete[] operators.

I'm not sure why you get the warnings.. I remember I once got some of those too, but I don't quite remember the reason anymore.

Possibly it may be because of some other library, that you are using, is overloading the new and delete operators too. In general, the memorymanager should be the last thing to include in your source, so that any other library won't screw up the operator overloads.

Or it might be that you get the warning if your class does not have any destructor method defined. Adding dummy ~MyClass { } methods might do the trick.

And about that sub edx,4.. It's probably just fine. The memory manager will actually allocate more memory than your class would need, adding a bit extra memory before and after the actual data. This way it can check for buffer overruns (or whatever they are called) - the usual 0xDEADBEEF thing which you may have heard about. So the memorymanager does not actually return the real allocated memory pointer to you, but a pointer somewhere inside the real allocated memory.

So that -4 may be correct. The usual reason for the "Allocation not found" is that:

Either you are deleting some data twice or you are allocating the data (using the new operator) somewhere in the code where the memorymanager is not included - Either you have forgotten to add the #include to some cpp file, or you have a new operator in some header, in which case you need to add the memorymanager include to that header too. These are the usual reasons in my experience.

And yes I do know the author of that code, I work with him (and I have tweaked that memorymanager myself too, although that version is the original version that I have not touched).
Back to Top View jpkokkon's Profile Search for other posts by jpkokkon Send Private Message Add to Buddy List
 
Popolon
Admin Group
Admin Group
Avatar

Joined: 05 November 2002
Location: Spain
Posts: 3135
Posted: 05 November 2003 at 15:16 | IP Logged Quote Popolon

Well, surely the warnings are for the reason you tell, classes without standard destructor defined. But I don't mind those warnings.

About substracting 4. I'm sure it's not right. I already knew that the memory_manager allocates a structure ALLOCATION, that allocates some bytes for extra info (I was very curious on how a memory debugger could be implemented! ). But this ALLOCATION structure has a pointer called DataPointer. This DataPointer points to 0x00e80180. This is the value passed to the hash table to store the info of which memory blocks have been allocated. Afterwards, to retrieve the info from the has table, the value passed to the hash function is 0x00e8017c, thus not finding the object.

Any way, the substraction operation is performed BEFORE calling the delete operator, and therefore is inserted there by the compiler, and not by the memory_manager itself.

I think that maybe the problem is that some other library is also overriding the NEW/DELETE operators. I'll try to include the memorymanager at the end of the includes instead of at the beginning of them...

[ some minutes later ]

The problem was exactly that: I was including the memory manager at the beginning. May be some other library was redefining NEW/DELETE. Now it works fine! (and there is no substraction before the call the the delete!)

I've to say that this library is wonderful!! Can I distribute it? A friend of mine has seen it in my computer and he also wants to use it!
I still haven't found any serious bug (just those delete -> delete[]) but I'm scanning all the program now!!!
Back to Top View Popolon's Profile Search for other posts by Popolon Visit Popolon's Homepage Send Private Message Add to Buddy List
 
Popolon
Admin Group
Admin Group
Avatar

Joined: 05 November 2002
Location: Spain
Posts: 3135
Posted: 06 November 2003 at 16:18 | IP Logged Quote Popolon

Source code completely revised!!
There were about 30-40 places where objects were not properly deleted! So, about 5000-6000 pointers were left without deletion in a normal execution of just loading a game and playing for 10-20 seconds...
I can imagine now why the program consumed so much memory!

However, I've found a small problem: I use a library called SGE for the collision detection. That library has a type called "cmap" (or something like that), that is created with a function called "sge_make_cmap", and freed with "sge_destroy_cmap". Each time I call sge_destroy_cmap, I got an exception from the memory manager saying that I'm trying to delete a piece of memory that wasn't allocated... It's somehow strange since SGE is linked through a DLL, and I only include a .H file that doesn't contain any call to NEW or DELETE...

I'll try to investigate a little bit more on this, but a part from this small problem, the rest of the program is noe leak free!!!
Back to Top View Popolon's Profile Search for other posts by Popolon Visit Popolon's Homepage Send Private Message Add to Buddy List
 
jpkokkon
Newbie
Newbie


Joined: 09 October 2003
Location: Finland
Posts: 23
Posted: 06 November 2003 at 17:58 | IP Logged Quote jpkokkon

That SGE problems sounds quite strange.. It really sounds like there would be a memory allocation inside the dll (without memorymanager) and then that would be deleted somewhere in the SGE header (with memorymanager)... But if that's not the case, then it must be some other weird effect..

There may be problems with the memorymanager and some libraries. I guess the only easy way around the problem would be to avoid using memorymanager in such files that use such libraries - of course it may prove out to be a bit complicated if the memorymanager is included in some common header. (or if you are allocating some memory in that file and then it is destroyed elsewhere or vice versa.)

And about distributing the memorymanager, well it does say in the readme file that "do whatever you like with the code, as long as the copyright notice is not modified" (in finnish). So basically, I guess you could distribute the original zip file.. A small problem of course will be the finnish language - obviously the code has been primarily meant for finnish coders.

I can ask the author about that, and ask if he wants to make a quick translation to the finnish readme to get an english version for distribution.
Back to Top View jpkokkon's Profile Search for other posts by jpkokkon Send Private Message Add to Buddy List
 
Popolon
Admin Group
Admin Group
Avatar

Joined: 05 November 2002
Location: Spain
Posts: 3135
Posted: 06 November 2003 at 18:39 | IP Logged Quote Popolon

As you say, it looks as if the "delete" was defined in the header, but I've searched in all the SGE headers,and there's no "delete" defined. In fact, the definition of the function is like this:

DECLSPEC void sge_destroy_cmap(sge_cdata *cd);

and the function (in the source code of the SGE library), is like this:

//==================================================================================
// Removes collision map from memory
//==================================================================================
void sge_destroy_cmap(sge_cdata *cd)
{
     if(cd->map!=NULL)
          delete [] cd->map;
          
     delete cd;
}

So, everything looks ok...

I've created a small project that just has a single .cpp file that just initializes SDL, creates a sge_cmap object, and tries to destroy it. And the memory manager throws an exception!
I include it here:
EZDA3_SGE_test.zip

May be you or your friend are interested on debugging the memory_manager (in the case that the bug is in the memory_manager). But I think that it has to be something related to the way SGE was compiled or linked... it's somehow curious...

Here's how the sge_cdata structure is allocated, notice the "(nothrow)" expresions by the "new" operators. Can they be the cause? I've never seen using a new operator like this before...

//==================================================================================
// Makes a new collision map from img. Set colorkey first!
//==================================================================================
sge_cdata *sge_make_cmap(SDL_Surface *img)
{
     sge_cdata *cdata;
     Uint8 *map;
     Sint16 x,y;
     Sint32 offs;
     int i;
     
     cdata=new(nothrow) sge_cdata;
     if(!cdata){SDL_SetError("SGE - Out of memory");return NULL;}
     cdata->w=img->w; cdata->h=img->h;
     offs=(img->w*img->h)/8;
     cdata->map=new(nothrow) Uint8[offs+2];
     if(!cdata->map){SDL_SetError("SGE - Out of memory");return NULL;}
     memset(cdata->map,0x00,offs+2);
     
     map=cdata->map;
          
     i=0;
     for(y=0; y < img->h; y++){
          for(x=0; x < img->w; x++){
               if(i>7){i=0;map++;}
               if(sge_GetPixel(img, Sint16(x),Sint16(y))!=img->format->colorkey){
                    *map=*map|sge_mask;     
               }
               i++;
          }     
     }
     return cdata;
}
Back to Top View Popolon's Profile Search for other posts by Popolon Visit Popolon's Homepage Send Private Message Add to Buddy List
 
Popolon
Admin Group
Admin Group
Avatar

Joined: 05 November 2002
Location: Spain
Posts: 3135
Posted: 06 November 2003 at 18:42 | IP Logged Quote Popolon

btw, an english translation of the Finnish readme will be great! I can translate it to spanish after that. Some people at my lab are really interested on using it. Specially a guy that is suspecting that a library he's programming has a strange behaviour with the memory...
Back to Top View Popolon's Profile Search for other posts by Popolon Visit Popolon's Homepage Send Private Message Add to Buddy List
 

If you wish to post a reply to this topic you must first login
If you are not already registered you must first register

  Post ReplyPost New Topic
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum

Powered by Web Wiz Forums version 7.01
Copyright ©2001-2003 Web Wiz Guide

This page was generated in 0,3584 seconds.