View Single Post
 
Old 06-20-2014, 04:17 PM
CoolBlue's Avatar
CoolBlue CoolBlue is offline Windows 7 64bit Office 2013
Advanced Beginner
 
Join Date: Jun 2014
Location: Australia
Posts: 40
CoolBlue is on a distinguished road
Default Slow "comparison/replace" script

Quote:
Originally Posted by whatsup View Post
Hi CoolBlue

Yes that's exactly the problem. I did try the same way as you showed, and in case of your last example it can be done, because it's simple and you can calculate the required bytes. But usually it's unpredictable the requirement of an object to copy, and therefore it won't work, - that way.
Yep, I assume that the Any Type of the parameters of your MEM_Copy declaration will typecast any Object as a pointer to that object, so

Code:
Mem_Copy oTemp, lPtr, 4
Is like
Code:
Mem_Copy ObjPtr(oTemp), lPtr, 4
The problem is that you are overwriting the first 4 bytes (in this case) of an Object type variable structure with the first 4 bytes of a Range type variable structure, coz IPtr is a pointer to the base address of a Range Object.
For sure, this will corrupt the structure of oTemp.
Then when you do
Code:
Set ObjectFromPointer = oTemp
Excel will crash coz it doesn't find what it needs at the base address of oTemp because its corrupted already.

But I'm interested that you say you said you can calculate the required bytes... How do you do that? I've been searching for an explanation of the byte structure that VBA uses for storing it's various types: do you have that?

Quote:
Originally Posted by whatsup View Post
Now I gave some more thoughts to the function ObjectFromPointer(). That's because, what do I gain by copying the contents assigned to a pointer? Sure if still pointing to the same object (as in the example with objRange) I can ask if "Nothing" or use a property of the initial object to identify it. But in case the pointer is already assigned something else it will give me a hard time to keep the macro out of trouble.
Therefore I wonder if it would make sense to read always a fix parameter of length for example 32 and just compare the results. If they show a difference, it will tell that something else got assigned to the pointer, and that's good enough. .
Yep, I had the same thought. Did you try my example with a Class Object? I arbitrarily set the bytes count to 32*4 just to get a look at the structure, to search for the value I set the properties to (hex AAAAAA, or something like that) and you can see it clearly, a little way into the buffer. Try it and you will see what I mean.
But anyway, it seems like very start of that structure is always set to zeros when the variable is erased by VBA's memory management. So you can always see that the object has been erased. This is the best indication I've seen so far to show the life cycle of the variable.
Here are a few sample runs...
Code:
objCls : 0x18E11A58 : 0x04C0031500000000741AE1181C753904047539040000000000000000ECEC831A0100000000000000000000000F10000000000000AAAAAA00ABABAB00BCBCBC00F4E9101500000000000000009C0601005FB4AF2E060100802300E7719425E771
objCls : 0x18E11A58 : 0x0000000000000000741AE11800000000000000000000000000000000ECEC831A0100000000000000000000006E1C000000000000AAAAAA00ABABAB00BCBCBC00F4E9101500000000000000009C0601005FB4AF2E060100800D00530041004100

objCls : 0x18E11A58 : 0x04C0031500000000741AE1181C753904047539040000000000000000ECEC831A0100000000000000000000000F10000000000000AAAAAA00ABABAB00BCBCBC00F4E9101500000000000000009C0601005FB4AF2E060100802300E7719425E771
objCls : 0x18E11A58 : 0x0000000000000000741AE11800000000000000000000000000000000ECEC831A0100000000000000000000006E1C000000000000AAAAAA00ABABAB00BCBCBC00F4E9101500000000000000009C0601005FB4AF2E060100802300E7719425E771

objCls : 0x18E11A58 : 0x04C0031500000000741AE1181C753904047539040000000000000000ECEC831A0100000000000000000000000F10000000000000AAAAAA00ABABAB00BCBCBC00F4E9101500000000000000009C0601005FB4AF2E060100804400E7719425E771
objCls : 0x18E11A58 : 0x0000000000000000741AE11800000000000000000000000000000000ECEC831A0100000000000000000000006E1C000000000000AAAAAA00ABABAB00BCBCBC00F4E9101500000000000000009C0601005FB4AF2E060100801800E7719425E771
And he you can see the reference counting doing its job...
Code:
objCls : 0x18E11950 : 0xEC2C0915000000006C19E118648948044C8948040000000000000000ECEC831A0100000000000000000000000F10000000000000AAAAAA00ABABAB00BCBCBC000000000004E9101500000000000000003EB4AF2EE50000880000000000000000
after exit...
objCls : 0x18E11950 : 0x00000000000000006C19E11800000000000000000000000000000000ECEC831A0100000000000000000000006E1C000000000000AAAAAA00ABABAB00BCBCBC000000000004E9101500000000000000003EB4AF2EE50000880000000000000000

objCls : 0x18E11950 : 0xEC2C0915000000006C19E118648948044C8948040000000000000000ECEC831A0100000000000000000000000F10000000000000AAAAAA00ABABAB00BCBCBC000000000004E9101500000000000000003EB4AF2EE50000880000000000000000
Set to Nothing...
objCls : 0x18E11950 : 0x00000000000000006C19E11800000000000000000000000000000000ECEC831A0100000000000000000000006E1C000000000000AAAAAA00ABABAB00BCBCBC000000000004E9101500000000000000003EB4AF2EE50000880000000000000000
after exit...
objCls : 0x18E11950 : 0x00000000000000006C19E11800000000000000000000000000000000ECEC831A0100000000000000000000006E1C000000000000AAAAAA00ABABAB00BCBCBC000000000004E9101500000000000000003EB4AF2EE50000880000000000000000
As you can see, the first 8 bytes is always cleared to zeros.
Quote:
Originally Posted by whatsup View Post
Just to avoid misunderstanding: I didn't say, that the reference count doesn't work at all. It's just as Bob put it "there might be circumstances when it doesn't".
In the moment we do with simple structures because it's about figuring out a way to keep track on ongoing things within memory. Therefore I'm expecting reference count doing allright and would be dissapointed if failing (though creating a new instance of an object was said in former times might be already to much for automatic deallocation, the same as for not handled errors).
AH, OK, fair enough. Yep, sure. Well I think we have a detection tool that works now, to a reasonable level of confidence, so the next thing I was thinking to do is to create some structures that will not be released - like a Class with a circular reference for example - and see how that behaves. I'll also try crashing out of the sub on an error to see if that doesn't release the variable as well.
Reply With Quote