Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

fix memory leak in {host,device}_vector::reserve #1447

Merged
merged 2 commits into from
Jun 8, 2021

Conversation

germasch
Copy link
Contributor

This fixes #1443 -- .reserve() did not actually deallocate the memory previously allocated when allocating a new, larger storage area. It also disables the capacity growing exponentially when using .reserve(), instead the vector will be grown exactly to the capacity specified, as is the case for std::vector.

See commit messages for some more detail.

germasch added 2 commits May 28, 2021 14:34
Inside of append(), for the case that the underlying storage
had to be reallocated to accomodate its new capacity, the
code is currently using the old storage (ie., `m_storage`) to do
the default construction, and possibly destruction when needing
to clean up after an exception.

It is more consistent to use the `new_storage` member functions to
do so -- after all we are constructing (or destroying) elements in
that `new_storage` here.

This is essentially a cleanup only, it doesn't actually change behavior,
since `new_storage` is created to use a copy of the allocator that's in
`m_storage`, so the `default_construct_n` and `destroy` functions called
are identical in practice -- it just makes this piece of code more consistent.
Currently, when using reserve() to actually grow the
storage in a vector, a new backend storage is allocated,
but the old one is never deallocated. A more minor unexpected
behavior that also occurred is that the vector would still apply
its exponential growth behavior, ie., it when taking a vector of
size 3 and calling `.reserve(4)` on it, one would actually end up
with a vector of size 6.

The logic to allocate the new storage, copy in the existing elements,
then destroy the old elements and swap in the new storage (which does
to the old storage being destructed and hence deallocated) is, essentially,
taken from how `.resize()` works. When growing a vector using `.reserve()`,
the new capacity will now be exactly what was specified in the call to
`.reserve()`.
@GPUtester
Copy link
Collaborator

Can one of the admins verify this patch?

@alliepiper
Copy link
Collaborator

Thanks Kai, this looks good to me. I'll start testing and target this for 1.13.

run tests

@alliepiper alliepiper self-assigned this Jun 1, 2021
@alliepiper alliepiper added the testing: gpuCI in progress Started gpuCI testing. label Jun 1, 2021
@alliepiper
Copy link
Collaborator

DVS CL: 30027183

@alliepiper alliepiper added the testing: internal ci in progress Currently testing on internal NVIDIA CI (DVS). label Jun 1, 2021
@alliepiper alliepiper added this to the 1.13.0 milestone Jun 1, 2021
@alliepiper alliepiper added testing: internal ci passed Passed internal NVIDIA CI (DVS). testing: gpuCI passed Passed gpuCI testing. and removed testing: internal ci in progress Currently testing on internal NVIDIA CI (DVS). testing: gpuCI in progress Started gpuCI testing. labels Jun 8, 2021
@alliepiper alliepiper merged commit 86b5b3d into NVIDIA:main Jun 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
testing: gpuCI passed Passed gpuCI testing. testing: internal ci passed Passed internal NVIDIA CI (DVS).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

thrust::{device,host}_vector::reserve() leaks memory
3 participants