boost::multiprecision and rocksdb::Slice string interaction c++

96 views Asked by At

Hi can someone explain what is happening here to me?

Version:
librocksdb-dev/bionic,now 5.8.8-1 amd64 [installed]
librocksdb5.8/bionic,now 5.8.8-1 amd64 [installed,automatic]
boost-cpp 1.74.0

#include <iostream>
#include <string>
#include <boost/multiprecision/cpp_int.hpp>
#include <rocksdb/db.h>

int main() {
    boost::multiprecision::checked_uint256_t check("115792089237316195423570985008687907853269984665640564039457584007913129639935");
    std::string test = check.str();
    rocksdb::Slice dbkey = check.str();
    std::cout << check << std::endl;
    std::cout << dbkey.ToString() << std::endl;
    dbkey = test;
    std::cout << dbkey.ToString() << std::endl;
    return 0;
}

output: 
115792089237316195423570985008687907853269984665640564039457584007913129639935
        9237316195423570985008687907853269984665640564039457584007913129639935
115792089237316195423570985008687907853269984665640564039457584007913129639935
1

There are 1 answers

0
parktomatomi On BEST ANSWER

This snippet is undefined behavior:

rocksdb::Slice dbkey = check.str();
/* ... */
std::cout << dbkey.ToString() << std::endl;

rocksdb::Slice is a "fat pointer" with a data pointer and a size, like C++20's std::span or C++17's std::string_view. It has no ownership of whatever you assign to it.

The result of check.str() is a temporary object, which means it gets destroyed at the end of the expression. After it was destroyed, the pointer stored in dbkey is no longer valid.

The way you generated the third line of output is the correct way to use rocksdb::Slice - one object to own the data, and a slice to view the data.