可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
vector <weight> decoy;
void clear_decoy() {
decoy.clear();
vector<weight> (decoy).swap(decoy);
}
In the above method clear_decoy()
, what does vector<weight> (decoy).swap(decoy);
mean please?
Does the method clear decoy
or not? Thanks!
回答1:
It creates a new vector of Weight
objects (which will be empty) and swaps it with decoy
.
The reason for this is that by default, std::vector<t>::clear
often doesn't actually reduce the storage used by a vector, it merely destroys all the objects contained there. This way, the vector has room to store more objects without reallocation in the future.
Sometimes, however, you want to trim the capacity in the vector. Swapping with a newly created vector (which lives until the end of it's line, and is therefore destroyed there) frees all the memory allocated by the vector.
回答2:
I've never seen that form before.
I have seen it written as:
vector<weight>().swap(decoy);
Which means "create a new empty vector, and swap it with the existing one.
vector<weight> (decoy).swap(decoy);
To understand that, break in to parts.
vector<weight>(decoy)
create a new vector (with it's contents copied from the now empty decoy). The new vector is an anonomous temporary, so let's pretent it's name is newvector
.
newVector.swap(decoy);
swaps the new vector with decopy.
(Updated per comments to fix bug)
回答3:
That code is a failed attempt to use a common trick to ensure the memory allocated by the vector is freed. It may or may not actually do that, depending on whether or not the vector's copy constructor allocates memory to match the other vector's size, or its capacity.
To reliably free the memory, use the following:
void clear_decoy() {
vector<weight>().swap(decoy);
}
This creates a temporary empty vector (with little or no memory allocated), swaps this with decoy
so that the memory is now owned by the temporary, then destroys the temporary, freeing the memory.
回答4:
clear
removes all entries from the vector, but may not necessarily deallocate the space. This swap idiom restores the vector to having no space allocated.
回答5:
As 0A0D mentions, the effect of swap
is to exchange the underlying controlled memory between the two vectors. But this warrants a little more explanation.
When you clear
a vector
, the elements are removed from it at least as far as the programmer is concerned. size()
becomes zero and capacity()
may or may not change. But the Standard doesn't guarantee that the memory used by the vector will actually be returned back to the operating system. So if you had 1000 elements in the vector before the clear()
and each took 1000 bytes memory, after the clear()
each element's destructor is called, but the vector may still be holding on to a 1,000,000 byte allocation.
This is sometimes undesirable. The 'swap trick' you note above has the effect of exchanging the controlled memory between the two vectors. Hence decoy
ends up with it's controlled memory reset.
Here is what is happening step-by-step:
decoy
elements are each erased
.
The elements' destructors are
called, and the vector's size()
becomes zero. The actual memory may
not be deallocated.
- A new vector is constructed on the stack (
vector<weight> (decoy)
) and the elements from decoy
are copied in to it. Since decoy
was just clear()
ed, no elements are copied in to the temporary vector. However, see edit below. You don't know that the controlled memory is not swapped.
- The temporary vector's and
decoy
's memory are swapped (.swap(decoy);
) resulting in decoy
being both cleared and it's memory transferred to the temporary.
- The temporary falls off the stack, resulting in it's memory being deallocated.
This is referred to as "the swap trick".
EDIT: As Mike mentions, the original programmer is doing it wrong. The temporary should not be constructed based on decoy
, it should just be default constructed. You don't know for sure that swap()
will only copy the elements and not the controlled memory underneath.
回答6:
With clear,
All the elements of the vector are
dropped: their destructors are called,
and then they are removed from the
vector container, leaving the
container with a size of 0.
Swap just swaps the two vectors,
Swap content
Exchanges the content of the vector by
the content of vec, which is another
vector of the same type. Sizes may
differ.
After the call to this member
function, the elements in this
container are those which were in vec
before the call, and the elements of
vec are those which were in this. All
iterators, references and pointers
remain valid for the swapped vectors.
It seems you are swapping nothing really and just restores to default allocation. Clear can deallocate but it sometimes does not. You are not only reducing the size but lessening the space allocated with the swap statement.