Mistrel wrote:The question for Fred/freak here is: when reusing an existing #PB_Any ID does it resize the internal ID table or simply reuse the existing entry. If this is the case then I believe the warning would be more suited for numbers larger than 100,000 which do not already exist.
If you pass a #PB_Any created number (which is usually very high as it is a direct memory address) PB will try to allocate the object among the static numbers (which are allocated in an array), so you get a very large array as a result and tons of wasted memory. Thats why there is the debugger message.
PB Objects are managed in the following way at the moment:
- If you pass in your own number, the object structures are kept in an array, indexed by this number (for this reason, passing a high number is bad)
- If you use #PB_Any, the returned value is a direct memory address of an allocated object structure
It is slightly more complicated in thread mode, but that doesn't matter here. This way works fine because all OS actually reserve low memory locations for system use and do not return them as a result of a usermode memory allocation, so there are no collisions.
The reason why reusing a #PB_Any number is not possible is because it cannot be determined wether the number you passed in actually references a valid PB object without comparing the number to all existing objects (which is very slow of course). For the static numbers it is easy to verify as we only have to check if the number fits the bounds of the array and then look at the entry to see if it is valid.
Take these sequences:
Code: Select all
CreateImage(1, ...)
FreeImage(1)
CreateImage(1, ...)
a = CreateImage(#PB_Any, ...)
FreeImage(a)
CreateImage(a, ...)
The first sequence works perfectly well. You can even skip the FreeImage() as PB automatically frees an object if the number is reused. Not so for the second sequence though. After the 'FreeImage(a)' call, a is actually the address of now freed memory. If the next CreateImage(a, ...) tries to reuse it you get a crash, or worse you just corrupt some random part of your program's memory.
So you see, the two number systems cannot easily be treated in the exact same way (without a big speed hit for verifying objects). We could allow the reuse of 'a' as a number if the object was not freed inbetween, but then it is still not fully the same behavior and even more dangerous in terms of hard to find bugs in my opinion.
That said, the debugger could provide a more helpful message if you try to use a #PB_Any number like this. (because the debugger actually does the slow object verification). This should make things a bit more clear.
(Note: The internals of the object management are just that: internals. It can change anytime in the future. Don't rely on this.)