[2024] zlib z_stream isn't moveable
Table of Contents
1. TL;DR
Be aware that zlib
's z_stream
struct cannot be moved.
Presume it contains internal pointers to itself.
2. Setup
- Using
zstreambuf
(provided as byproduct of my cmake-examples project) I ran into errors after move assignment. - Making
zstreambuf.open()
work with azstreambuf
that's already been used for i/o. - Attempted to cleanup state within
zstreambuf.close()
, using move assignment onbuffered_inflate_zstream
andbuffered_deflate_zstream
.
3. Problem + Diagnosis
- Unit testing revealed that uncompress failed after second
zstreambuf.open()
. - It turns out that although zlib's
z_stream
struct is fully exposed (to work with zlib, application code should declare a variable with typez_stream
), thez_stream
struct can't be moved to another location. Presumably at least one of (::deflateInit2()
,::inflateInit2()
) does some address-dependent computation involving one or morez_stream
members.
4. Solution
Replace
z_stream
member with a pointer:Instead of:
// compression/include/compression/base_zstream.hpp #include <zlib.h> struct base_zstream { // ...omitted... z_stream zstream_; };
write:
// compression/include/compression/base_zstream.hpp #include <utility> struct base_zstream { // ...omitted... std::unique_ptr<z_stream> p_native_zs_; };
Then implement
::swap()
etc by swapping pointers.