LevelDB 在删除 LevelDB 实例时断言
LevelDB asserts when deleting the LevelDB instance
当我尝试删除 leveldb 实例时,我得到了一些非常烦人的断言,但我不确定为什么会发生这种情况!
断言发生在 version_set.cc 文件中:
void VersionSet::AppendVersion(Version* v) {
// Make "v" current
assert(v->refs_ == 0); // <---??? how do I avoid this assertion?
// the rest of the source code is available in the link to version_set.cc
}
此外,它在同一文件的另一个位置断言:
Version::~Version() {
assert(refs_ == 0); // <-- Again... how do I avoid this one too?
// the rest of the source code is available in the link to version_set.cc
}
以下是有关我系统中使用情况的更多背景详细信息,我有一个:
- 类
ExtStorage
(扩展存储(,具有LevelDB::DB
实例。 - 类
EextStorageDotNet
,它是围绕ExtStorage
的 C++/CLI 包装器。 - 类
AltStorage
,它包含指向 ExtStorage 类(通过构造函数传递(的指针: - 类
AltStorageDotNet
,它是围绕AltStorage
的 C++/CLI 包装器。
备用存储类如下所示:
class AltStorage{
ExtStorage* instance;
public:
AltStorage(ExtStorage* extStorage):instance(extStorage){}
~AltStorage(){
delete instance;
instance = NULL;
}
};
ExtStorage
类如下所示:
class ExtStorage{
leveldb::DB* mydb;
public:
ExtStorage(/*some parameters*/){
mydb = new leveldb::DB(/*parameters*/);
}
// Destructor
~ExtStorage() {
Close();
}
// deletes the leveldb::DB instance
void Close() {
if(mydb == NULL) {
delete mydb; // <-- Asserts every time I get here when using with the AltStorageDotNet
mydb= NULL;
// Close the L1 and L2 caches
// only once (
}
}
}
AltStorageDotNet
类如下所示:
public ref class AltStorageDotNet{
AltStorage* altInstance;
ExtStorageDotNet^ extInstance;
public:
AltStorageDotNet() {
ExtStorage extStorage = new ExtStorage(/*params*/);
altInstance = new AltStorage(extStorage);
extInstance = gcnew ExtStorageDotNet(extStorage);
}
~AltStorageDotNet(){
delete altInstance;
altInstance = NULL;
// no need to delete extInstance since it was created with gcnew
}
!AltStorageDotNet(){
delete altInstance;
altInstance = NULL;
// no need to delete extInstance since it was created with gcnew
}
inline ExtStorageDotNet^ GetExtInstance(){return extInstance;}
};
DotNet 包装器如下所示:
public ref class ExtStorageDotNet{
private:
ExtStorage* instance;
public:
ExtStorageDotNet(ExtStorage* extStorage){
instance = extStorage;
}
~ExtStorageDotNet(){
delete instance;
instance = NULL;
}
!ExtStorageDotNet(){
delete instance;
instance = NULL;
}
void Close(){instance->Close();}
};
每当我在 C# 应用程序中使用 ExtStorageDotNet
包装器时,一切正常,并且没有断言。但是,当我使用 AltStorageDotNet
包装器并访问 ExtStorageDotNet
包装器时,我会在关闭数据库时获得断言。这都是测试套件的一部分,我在其中为每个测试用例初始化一个实例,并在每个测试用例后关闭它;在新测试用例开始之前,关联的数据库文件将被删除。我看不出有任何理由应该发生这种情况,并且断言无助于追踪问题。
我摆脱了嵌套引用,但这并没有解决问题。事实证明,导致此问题的问题并不完全是我所关注的。当用户获取数据库的迭代器,并且无法在删除数据库之前删除迭代器时,会出现此问题。这在与级别数据库相关的谷歌组中进行了讨论。
// Caller should delete the iterator when it is no longer needed.
// The returned iterator should be deleted before this db is deleted.
virtual Iterator* NewIterator(const ReadOptions& options) = 0;
当用户获得迭代器时,他们应该在删除数据库之前将其删除,否则他们将获得上述断言。
它是否与您的断言有关,但这段代码肯定会导致内存损坏。ExtStorageDotNet
和AltStorageDotNet
都是一次性的和可定稿的,并且(直接或间接地(delete
ExtStorage
的实例 - 总是,一个会在另一个已经有之后delete
它。
另外,正如我在评论中所说,您的代码中的注释说no need to delete extInstance since it was created with gcnew
很不对劲 - 有关详细信息,请参阅此答案。(我假设你知道C#,因此了解IDisposable
;如果你不了解,那么你真的需要做一些阅读。
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- uint_not_usable_without_attribute在业力规则中使用数字生成器时静态断言失败
- C++ 使用增强正则表达式库时断言崩溃
- 从 exe 文件 (Visual Studio ) 启动时调试断言失败
- 如何将向量断言到特征矩阵
- OpenCV - Python 断言错误:SAD 算法 - 立体相机视差图计算
- 使用 Google Test 对自定义断言函数进行单元测试
- 断言"id < 0"在Qt ActiveX中失败
- 初始值设定项列表构造和静态断言
- 在 CppUnit 中测试中止断言失败
- 使用扫描的调试断言失败
- MS 本机单元测试 - 断言::线程失败不起作用
- 如何断言 CRTP 的函数为最终函数?
- 迭代器跳闸视觉C++ 2017 断言
- 如何在 google test in windows 中管理断言
- 为什么我的Qt程序在断言失败后继续运行?
- 在C++中禁用断言宏
- 宏"断言"会在 C++20 中删除吗?
- 在 constexpr 函数中断言
- LevelDB 在删除 LevelDB 实例时断言