【问题标题】:Received signal: Segmentation fault (11) while using Rocksdb接收到的信号:使用 Rocksdb 时出现分段错误 (11)
【发布时间】:2022-01-11 20:15:51
【问题描述】:

我使用 Rocksdb 作为程序的数据库(C++)。对于一个用例,我正在制作一个以下格式的键来存储:key=

从键访问“字符串类型元素”数据时出现以下错误:

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-element = *reinterpret_cast<const string-type*>(iter->key().data() + prefix.size());

        // some stuffs here
    }
}

我的尝试:

正如您在上面的代码中看到的那样,我指出了错误行。由于错误是分段错误 (11),这通常意味着尝试未定义/外部内存位置,所以我的猜测是 reinterpret_cast 无法将“字符串类型元素”元素的大小推断为 std ::string 与“int”等不同,它不是固定大小,它最终会访问它不应该访问的内存部分......

我想问:

  1. 如果实际上由于大小未知而无法从密钥之间提取 std::string,我们该怎么办?
  2. 我提到的问题是否还有其他原因以及如何解决?

【问题讨论】:

  • 看来您需要将数据从 (iter-lkey.data() + size) 复制到字符串的末尾。目前你正试图取消引用一个指针并神奇地复制它指向的东西......
  • @sashan 字符串的结尾是什么?

标签: c++ segmentation-fault rocksdb


【解决方案1】:

reinterpret_cast 是一个非常危险的工具,只能在特殊情况下使用,而这里没有。查看 std::string 构造函数,您会发现一个接受指向以空字符结尾的字符数组的指针。目前尚不清楚iter-&gt;key().data() 的类型是什么,但如果它是一个以null 结尾的字符串,您可以将行更改为:

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

从前缀后面的部分数据初始化string-type。

在你的例子中,reinterpret_cast 试图假装指向的数据是一个字符串对象,它不仅仅是字符类型的原始字节,而且还有其他结构元素。

【讨论】:

  • 您可以快速浏览rocksdb 数据库概述来解决此问题
猜你喜欢
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多