首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LevelDB在删除LevelDB实例时断言

LevelDB在删除LevelDB实例时断言
EN

Stack Overflow用户
提问于 2011-08-17 23:10:44
回答 2查看 750关注 0票数 2

当我试图删除leveldb实例时,我得到了一些非常恼人的断言,我不知道为什么会发生这种情况!

断言发生在set.cc文件中:

代码语言:javascript
复制
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
}

此外,它在同一文件中的另一个地方声明:

代码语言:javascript
复制
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包装器。

备用存储类如下所示:

代码语言:javascript
复制
class AltStorage{
    ExtStorage* instance;
public:
    AltStorage(ExtStorage* extStorage):instance(extStorage){}

    ~AltStorage(){
        delete instance;
        instance = NULL;
    }
};

ExtStorage类如下所示:

代码语言:javascript
复制
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类如下所示:

代码语言:javascript
复制
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包装器如下所示:

代码语言:javascript
复制
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();}
};

每当我在我的ExtStorageDotNet应用程序中使用C#包装器时,一切都很好,没有断言。但是,当我使用AltStorageDotNet包装器并访问ExtStorageDotNet包装器时,我在关闭数据库时得到断言。--这都是测试套件的一部分,在测试套件中,我为每个测试用例初始化一个实例,并在每个测试用例之后关闭它;关联的数据库文件在新的测试用例开始之前被删除。,我不知道它为什么会发生,断言对跟踪问题没有帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-03 21:25:42

我去掉了嵌套的引用,但这并没有解决问题。事实证明,造成这一问题的并不完全是我在看的地方。当用户获得数据库的迭代器并在删除数据库之前无法删除迭代器时,就会发生此问题。这在一个与db级相关的google组中得到了讨论。

代码语言:javascript
复制
// 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; 

当用户获得迭代器时,他们应该在删除db之前删除它,否则他们将得到上面提到的断言。

票数 3
EN

Stack Overflow用户

发布于 2011-08-17 23:31:38

我不知道它是否与您的断言相关,但这段代码肯定会导致内存损坏。ExtStorageDotNetAltStorageDotNet都是一次性的和可终结的,两者(直接或间接)都是ExtStorage的实例--无一例外,一个会在另一个已经拥有的情况下将其delete化。

另外,正如我在我的评论中所说的,代码中的注释说no need to delete extInstance since it was created with gcnew是很遥远的--详细信息请参见这个答案。(我假设您了解C#,因此了解IDisposable;如果您不了解,那么您确实需要进行一些阅读。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7100634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档