Q:

How to take QByteArray from std::optional and leave std::nullopt without additional mallocs? 

I need to write a function that takes ownership of an optional<QByteArray>'s underlying array. 
In Rust, it is done by this way:
fn my_func(f: &mut Option<Box<[u8]>>) -> Box<[u8]> {
     //how to do "take" in c++17? 
     f.take().unwrap()
}

I know about std::move, but as far as I understand, this code will malloc data for a new array, swap pointers, and drop unneeded QByteArray:
std::optional<QByteArray> optarr = ...
QByteArray optarr = std::move(*myopt);
optarr.reset()

Is there any way to do this as well as in Rust (that is, without allocating memory for temporary QByteArray)? 

A:

Your assumption about std::move is wrong.  Roughly speaking std::move casts to an rvalue reference, no actual code is generated in itself by that.  The following line will create a QByteArray on the stack by calling its move constructor. 
QByteArray optarr = std::move(*myopt);

The move constructor initializes the Data pointer from the other QByteArray and replaces the other's data pointer with pointer to shared empty data.  No malloc is involved, just two pointer assignments. 
The implementation of the move constructor looks like this:
inline QByteArray(QByteArray && other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }

So your code is actually doing what you want. 

A:

The equivalent† function in C++ would be:
auto func(optional<QByteArray>&& o) -> QByteArray
{
    return std::move(o).value();
}

std::move(o) gives you an rvalue of type optional<QByteArray>.  Invoking value() on that rvalue gives you a QByteArray&& (or throws if o is disengaged).  That rvalue of type QByteArray is used to move construct the return object.  This move construction is cheap, just a few pointer assignments - no memory allocation happens. 

†Almost equivalent.  Note that o here does not end up as a disengaged optional, unlike in Rust.  It is still engaged, just holding an empty QByteArray.  Truly equivalent, if really desired, would be:
auto func(optional<QByteArray>&& o) -> QByteArray
{
    QByteArray result = std::move(o).value(); // NB: not a reference
    o.reset();                                // or '= nullopt', or '= {}'
    return result;                            // NB: no need to move
}

