Memory error on freememory()

Everything else that doesn't fall into one of the other PB categories.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Memory error on freememory()

Post by pdwyer »

The code below works fine but similar code in my app generates an error:
[ERROR] Invaid memory access. (read error at address 9908301)

The error occurs on the line with "Freememory" on it and usually does so on second time it's called.

I was wondering if since I'm reallocating memory inside a function on that pointer and that pointer has a different name inside the function that this is causing a problem...

Any other ideas what might cause this? I'm not sure where to look as I don't know what kinds of situations freememory would fail

Code: Select all

Procedure WorkWithMem(*Ptr)
    *Ptr = ReAllocateMemory(*Ptr,10)
    ; do all sorts of things here with the memory but don't free it
EndProcedure


*Ptr1 = AllocateMemory(1)
WorkWithMem(*Ptr1)
FreeMemory(*Ptr1)

*Ptr1 = AllocateMemory(1)
WorkWithMem(*Ptr1)
FreeMemory(*Ptr1)
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Have a look at Freak's blog regarding heap corruption :

http://www.purebasic.fr/blog/
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Hang on.... just a cotton picking minute! :wink:

ReallocateMemory() will sometimes move the memory completely (usually when re-allocating a much larger area than the original!) In these circumstances you MUST take note of the address of the new memory buffer!

In your code we can thus see if indeed the memory buffer is moved because of the Reallocation then you could well be attempting to free a buffer which is no longer valid!!!

To see this run the following and alter the 200000 until you notice the two memory buffers have different addresses. When this happens the program will crash because the FreeMemory() is trying to free an invalid buffer (because the buffer has moved!)

Code: Select all

*MemoryID = AllocateMemory(1000)
Debug *memoryID
*NewMemoryID = ReAllocateMemory(*MemoryID, 200000) ; need more memory
Debug *NewMemoryID

FreeMemory(*MemoryID)
If this is indeed your problem (as would seem quite likely!) then you will need to keep a better track of the memory buffer etc.

**EDIT : yes I can get your code to crash quite easily which does indeed suggest that this is the problem. I'll post a fix in a minute.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Fix (pass the buffer by reference to the procedure which can thus alter the address etc.)

Code: Select all

Procedure WorkWithMem(*Ptr.LONG) 
  Protected mem
  mem = ReAllocateMemory(*Ptr\l,10) 
  If mem
    *ptr\l = mem
  EndIf
EndProcedure 


*Ptr1 = AllocateMemory(1) 
WorkWithMem(@*Ptr1) 
FreeMemory(*Ptr1) 

*Ptr1 = AllocateMemory(1) 
WorkWithMem(@*Ptr1) 
FreeMemory(*Ptr1) 
I may look like a mule, but I'm not a complete ass.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

<cringe>

I was hoping that this wasn't the case, I didn't really want to do level's of redirection, but I really couldn't work out how the compiler would keep track from the original name<->mem location mapping otherwise.

Thanks for posting that fix, I've had problems working out how to do multi level redirection in PB, Sytax like **Ptr1 would be nice :P
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Well, you can of course avoid using pointers if you want.

As for multi-dereferencing; I find this easiest via pointers to structures which themselves contain pointers to other structures which themselves... It all works quite nicely and I am a liitle more comfortable with this than ***pointer etc. :)
I may look like a mule, but I'm not a complete ass.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Hang on.... just a cotton picking minute! :lol:

When you free the memory again outside the function, are you freeing the original 1byte or the new 10 bytes?

I tried:

*Ptr\l = ReAllocateMemory(*Ptr\l,10)

as a shorcut but I got the error again (this time the the reallocate second time around, not the free)

I suspect I'm not quite understanding this
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

The 10-byte re-allocation replaces the original 1-byte allocation completely. There is only ever one valid memory buffer.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

The problem with your shortcut :

Code: Select all

*ptr\l = Reallocate...
is that ReallocateMemory() will return zero if there is an error. Now in these cases you do not want to over-write the address of the original buffer which will still remain valid. Hence my code does not use this shortcut! :wink:
I may look like a mule, but I'm not a complete ass.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

I'm still getting errors though :?

Need to look at this a bit deeper, I think you fix is good but something else I'm doing is screwing with it
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

It's only failing with the debugger on :?

If I use "debug *ptr" on the line before the freememory I get one address and then when the app dies on that following line then the invalid memory address in the error is different to the address that was just shown. Matching this with the original address that was allocated I can see it hasn't changed so I don't know if freememory works differently with the debugger on or something :(

Worrying though
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

I read the blog you linked , added the function... I have a memory allocation heap corruption! :cry:

I came back to the blog because I changed the way the code works so that there were no reallocs in the proc but I still got the error!

Atleast this helps me look for the problem in the correct place!

Thanks
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
Deeem2031
Enthusiast
Enthusiast
Posts: 216
Joined: Sat Sep 20, 2003 3:57 pm
Location: Germany
Contact:

Post by Deeem2031 »

Maybe this helps to find the problem: http://www.purebasic.fr/english/viewtopic.php?t=35095
irc://irc.freenode.org/#purebasic
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Cheers,

That puts the same sort of check as Freak's at each line? I'll keep that for future reference, as I've filled my code up with Freaks tests and found where the error is, one of those nightmare areas in a completely different part of the progie that took ages to write where I got a little bit too carried away with the math on a pointer for a memory copy :lol: I was out by one finishing a buffer on a "64" instead of "63" and the code worked fine till I added a search function to a different spot which got it's heap overwritten by the previous code.

I just assumed that the new code added that generated the error would be where the error was, in this case the error lurked like Jaws waiting for someone new to jump into the water! :shock:
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Easy mistake to do, forgetting that when it comes to memory pointers 63 actually means the 64th byte :lol:
Post Reply