UP | HOME

[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 a zstreambuf that's already been used for i/o.
  • Attempted to cleanup state within zstreambuf.close(), using move assignment on buffered_inflate_zstream and buffered_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 type z_stream), the z_stream struct can't be moved to another location. Presumably at least one of (::deflateInit2(), ::inflateInit2()) does some address-dependent computation involving one or more z_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.

Author: Roland Conybeare

Created: 2024-09-08 Sun 18:01

Validate