If RestoreObj::Size() returns a value that exceeds 4000000 (~4Mb) then 3ds Max may exhibit inconsistent behavior then not every object passed to theHold. Put() appears in then Undo/Redo Menu, some of them of them are skipped.
The undo manager (the global instance of the Hold class named theHold) has a limit of 4 MB ( 8 * 500 * 1024) for all the restore objects in the Undo manager in 32 bit versions of 3ds Max. The 64 bit versions of 3ds Max has limit of 40 MB (80 * 500 * 1024) for all the restore objects. This is the amount of memory actually used. It is not pre-allocated or anything like that.
Note: In versions of 3ds Max prior to 3ds Max 2008, this limit was 500 KB.
When you attempt to put restore objects into the undo manager, it adds the sizes of the restore objects. That is the values you return in RestoreObj::Size(). This value is added to the size of the currently existing undo stack. If the new number is greater than 3/4 of the limit, then it rejects all the restore objects put between begin / accept pairs.
The decision to accept or reject your restore object is not done when you call Hold::Put(), but when you call Hold::Accept(). Also, at that time, the decision to accept or reject the restore object is not done on a case by case basis, but for all the restore objects you 'put' between a begin / accept pair. So if you put 4 restore objects between a begin / accept pair, where each is 1.2 MB, then when accept is called, the system will look at it as 4.8 MB of memory that needs to get added to the undo stack. And the decision to accept or reject will be performed accordingly.
If the undo manager rejects your restore objects, it will flush the entire undo stack, and delete the references to the restore objects. It will not automatically delete the memory referenced pointers, because they are reference targets, and are managed by the reference system.
RestoreObj::Size() is implemented by the developer. If you provide an incorrect size, you lose the protection that the undo manager will offer you.