Microsoft Office Forums

Go Back   Microsoft Office Forums > >

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #24  
Old 06-22-2014, 01:35 AM
CoolBlue's Avatar
CoolBlue CoolBlue is offline Slow "comparison/replace" script Windows 7 64bit Slow "comparison/replace" script Office 2013
Advanced Beginner
 
Join Date: Jun 2014
Location: Australia
Posts: 40
CoolBlue is on a distinguished road
Default

Quote:
Originally Posted by whatsup View Post
I should have said: I can imagine you can calculate the required bytes
That is if you've got a simple object and some insight on how objects are stored in memory.
Hmm. OK, that's too bad...
But anyway, the Byte Comb link you provided helps a little on that.
Quote:
Originally Posted by whatsup View Post
The crash with Mem_Copy oTemp, lPtr, 4 when checking afterwards is still some secret to me.
OK, you don't accept my explanation in post #35?
Well, its only a theory and I think it crashes before the line
Code:
Set ObjectFromPointer = oTemp
where I thought the problem was...
I also learned since that the first two options below will crash excel...
Code:
Sub crashMem_Copy()
Dim lptr As LongPtr
'    Mem_Copy lptr, ByVal 0, 4      'crashes excel
'    Mem_Copy lptr, ByVal lptr, 4   'crashes excel
    Mem_Copy lptr, lptr, 4            'is fine
End Sub
Quote:
Originally Posted by whatsup View Post
Of course I tried your example with the Class (ever since I trip over your "pionterToSomething" - I should have corrected it but I didn't). What I did change, was "name as string" to "strname as string" - you know why!
Ooops... and... Ooops! two good points.

Quote:
Originally Posted by whatsup View Post
But let's few our new "tool" - we still facing at least two problems:
1. An ordinary object requires only 4 bytes in memory. If I'm not mistaken, every set object to an object that already exists (without using the keyword "New") only is a number in the range of "As Long". But see the example it makes it clear:
Code:
Private Const coBytes As Long = 4
  
 Sub PointsToAnotherObject()
Dim objwks As Worksheet
    Debug.Print
    Debug.Print ObjPtr(Sheet1)
    pionterToSomething "Sheet1  ", ObjPtr(Sheet1), coBytes
Set objwks = Sheet1
    Debug.Print ObjPtr(objwks)
    pionterToSomething "objwks  ", ObjPtr(objwks), coBytes
    
End Sub
So in case you store ObjPtr(objwks) in a variable and check afterwards you might think the referencecount didn't work, because it's still there (unless you remove Sheet1 from your workbook). So there won't be any hint whether or not the 4 Bytes are freed, because afterwards you always will find the object of origin.
No problem, you can use VarPtr instead of ObjPtr and you will get the reference address that is stored in the local pointer. Your local variable objwks, is of course just a pointer with a reference to the worksheet object. You can see how this works here...

Code:
Sub getReference()
#If Win64 Then
    Const PTR_LENGTH As Long = 8
#Else
    Const PTR_LENGTH As Long = 4
#End If
Const coBytes As Long = 4
Dim objwks As Worksheet, lptr As LongPtr, objName As String, objwksPtr As LongPtr

    Debug.Print
'   Sheet1 Object reference and first coBytes bytes
    lptr = objPtr(Sheets(1)): objName = "Sheet1 "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using objPtr"
    
'   Using objPtr, can't diferentiate because the reference is resolved before reporting
    Set objwks = Sheets(1)
    lptr = objPtr(objwks): objName = "objwks "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using objPtr"
        
'   Using varPtr, can diferentiate.
'   The local Worksheet Object is treated as a reference, not an Object: the reference is not resolved
    lptr = VarPtr(objwks): objName = "objwks "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using varPtr"
    
'   The contents of the local variable (objwks) is the address of the global object but byte-reversed (little endian)
'   Load the reference into a LongPtr type and read back the byte-corrected (big endian) value of the reference
    Mem_Copy objwksPtr, ByVal VarPtr(objwks), PTR_LENGTH
    Debug.Print objName & vbTab & "points to: " & "0x" & HexPtr(objwksPtr)

'   Can also do this passing objwks as ByRef (default)
    Mem_Copy objwksPtr, objwks, PTR_LENGTH
    Debug.Print objName & vbTab & "points to: " & "0x" & HexPtr(objwksPtr)

'   Or like this...
    Mem_Copy ByVal VarPtr(objwksPtr), objwks, PTR_LENGTH
    Debug.Print objName & vbTab & "points to: " & "0x" & HexPtr(objwksPtr)
    
End Sub
Output:
Code:
Sheet1  : Address: 0x18240578 : Contents: 0xC0EA4C18    using objPtr
objwks  : Address: 0x18240578 : Contents: 0xC0EA4C18    using objPtr
objwks  : Address: 0x002AEF90 : Contents: 0x78052418    using varPtr
objwks  points to: 0x18240578
objwks  points to: 0x18240578
objwks  points to: 0x18240578
There are also some examples of how to call Mem_Copy (RtlMoveMemory) that might help to understand why it crashes.

And here you can see how the local variable's value is zero when its set to nothing...
Code:
Sub getReference2()
#If Win64 Then
    Const PTR_LENGTH As Long = 8
#Else
    Const PTR_LENGTH As Long = 4
#End If
Const coBytes As Long = 4
Dim objwks As Worksheet, lptr As LongPtr, objName As String, objwksPtr As LongPtr

    Debug.Print
'   Sheet1 Object reference and first coBytes bytes
    lptr = objPtr(Sheets(1)): objName = "Sheet1 "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using objPtr"
    
'   Using varPtr, can see the local variable is set to nothing.
'   The local Worksheet Object is treated as a reference, not an Object: the reference is not resolved
    lptr = VarPtr(objwks): objName = "objwks "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using varPtr, set to Nothing"
    
'   Using objPtr, can't diferentiate because the reference is resolved before reporting
    Set objwks = Sheets(1)
    lptr = objPtr(objwks): objName = "objwks "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using objPtr"
        
'   Using varPtr, can diferentiate.
'   The local Worksheet Object is treated as a reference, not an Object: the reference is not resolved
    lptr = VarPtr(objwks): objName = "objwks "
    Debug.Print PointerToSomething(objName, lptr, coBytes) & vbTab & "using varPtr"
    
'   The contents of the local variable (objwks) is the address of the global object but byte-reversed (little endian)
'   Load the reference into a LongPtr type and read back the byte-corrected (big endian) value of the reference
    Mem_Copy objwksPtr, ByVal VarPtr(objwks), PTR_LENGTH
    Debug.Print objName & vbTab & "points to: " & "0x" & HexPtr(objwksPtr)
    
End Sub
Output:
Code:
Sheet1  : Address: 0x18240578 : Contents: 0xC0EA4C18    using objPtr
objwks  : Address: 0x002AEF90 : Contents: 0x00000000    using varPtr, set to Nothing
objwks  : Address: 0x18240578 : Contents: 0xC0EA4C18    using objPtr
objwks  : Address: 0x002AEF90 : Contents: 0x78052418    using varPtr
objwks  points to: 0x18240578
Quote:
Originally Posted by whatsup View Post
2. If memory is freed, we might find "cleared to zero", but there might be something else assigned to the pointer. Up to now it only occured when testing with pointers to a Long-variable, but I think it always can happen. Therefore we better compare - keeping in mind point 1
If the memory is set to zero or overwritten, it makes no difference; it is still clear evidence that the variable's memory space has been released. And that's been my point all along...

In summary, I cant see any reason to set local objects to nothing at the end of a sub. Even if there is an error and the sub doesn't complete normally, or if there are structures that fool the reference counting, everything is still cleaned up in the former and the set to nothing does nothing extra in the latter.

I learned a lot from this exercise and added some nice routines to my library, so this has been most interesting!

For anyone who wants to run the above routines, here is a .bas file with everything you need... well its .txt but just need to change it to .bas and you can import into a module.
Attached Files
File Type: txt pointers and memory.txt (6.4 KB, 10 views)

Last edited by CoolBlue; 06-22-2014 at 08:38 AM. Reason: added .bas attachment; added outputs from debug window
Reply With Quote
 



Similar Threads
Thread Thread Starter Forum Replies Last Post
Wierd "script code" in a downloaded .doc file CNBarnes Word 2 10-18-2012 02:07 AM
Slow "comparison/replace" script replace data from variable with "sub and super script" from excel to word by vba krishnaoptif Word VBA 9 06-22-2012 05:08 AM
Slow "comparison/replace" script How to choose a "List" for certain "Heading" from "Modify" tool? Jamal NUMAN Word 2 07-03-2011 03:11 AM
Rules and Alerts: "run a script"? discountvc Outlook 0 06-15-2010 07:36 AM
An "error has occurred in the script on this page" decann Outlook 8 09-03-2009 08:54 AM

Other Forums: Access Forums

All times are GMT -7. The time now is 02:19 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Search Engine Optimisation provided by DragonByte SEO (Lite) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
MSOfficeForums.com is not affiliated with Microsoft