簡體   English   中英

接收到的信號:使用 Rocksdb 時出現分段錯誤 (11)

[英]Received signal: Segmentation fault (11) while using Rocksdb

我正在使用 Rocksdb 作為程序的數據庫(C++)。 對於一個用例,我正在制作一個以下格式的密鑰來存儲:key=< fix-prefix >< string-type >< foo-type >

從密鑰訪問“字符串類型”數據時出現以下錯誤:

Received signal: Segmentation fault (11)

用於迭代存儲數據的代碼類似於:

auto prefix = // defined here
auto from = // defined here
auto to = // defined here

std::unique_ptr<rocksdb::Transaction> trans(db_.BeginTransaction(rocksdb::WriteOptions()));

rocksdb::ReadOptions opts;
opts.snapshot = trans->GetSnapshot();
std::unique_ptr<rocksdb::Iterator> iter(trans->GetIterator(opts));

iter->Seek(from);

for (; iter->Valid() && iter->key().compare(to) < 0; iter->Next())
{
    if (iter->key().starts_with(prefix))
    {
        // This line of code is producing the error
        const auto string-type = *reinterpret_cast<const string-type*>(iter->key().data() + prefix.size());

        // some stuffs here
    }
}

我的嘗試:

正如您在上面的代碼中看到的那樣,我指出了錯誤的行。 由於錯誤是分段錯誤(11),這通常意味着嘗試未定義/在 memory 位置之外,所以我的猜測是reinterpret_cast無法推斷“字符串類型”元素的大小,因為 std::string 不是固定大小,不像“int”等,它最終會訪問它不應該訪問的 memory 部分......

我想問一下:

  1. 如果實際上由於大小未知而無法從密鑰之間提取 std::string ,我們能做些什么呢?
  2. 我提到的問題是否還有其他原因以及如何解決?

reinterpret_cast是一個非常危險的工具,只能在特殊情況下使用,而這里沒有。 查看 std::string 構造函數,您會發現一個接受指向以空字符結尾的字符數組的指針。 目前尚不清楚iter->key().data()的類型是什么,但如果它是一個以 null 結尾的字符串,您可以將該行更改為:

const auto string-type {iter->key().data() + prefix.size()};

從前綴后面的數據部分初始化字符串類型。

在您的情況下, reinterpret_cast試圖假裝指向的數據是一個字符串 object,它不僅僅是字符類型的原始字節,而且還有其他結構元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM