Yeah I forgot the increment....oops. The copy that calls release is the copy in the vector.
It is perfectly valid in COM to do this:
IUnknown *ptr1;
IUnknown *ptr2;
ptr2=ptr1;
So the interface is copyable. It doesn't actually create another interface but it creates a pointer to an already valid interface. But you are right the problem is not the vector cleanup it is the cleanup performed by the person using the vector which is what I was pointing out. Using user types with vectors normally requires some type of cleanup on the class's part - more than just the standard vector memory cleanup.
I'm not sure that clear has to be called. My books do not specifically say anything about having to call clear for correct cleanup to occur. However if you were using the vector of classes approach and the cleanup was in the destructor code for that class, then calling clear() for that vector would in turn call the destructor for that class which would in turn clean up correctly. Without calling clear there you would have to use the delete [] mechanism.
But since a vector can be of any type I think its a very important topic to discuss. Don't assume that everything is cleaned up automatically. The memory required for the vector is, but the class must still cleanup its own memory if it has allocated any as well as any resources it may have used.
So far my code works quite well for this very thing. The only error I have is in the sound code which for some reason is doing what you are telling me. It is calling release() twice for the same object when it shouldn't be. But none of the other vectors do this - each IDirect3DTexture9 interface represents one surface. I admit that my method could be dangerous if you were to misuse the class, but as long as you follow the rules it works very well and it is very fast.