【问题标题】:Deleting pointers that were allocated in another shared library删除在另一个共享库中分配的指针
【发布时间】:2011-06-06 19:29:07
【问题描述】:

更新(已解决):好吧,我是一个完全白痴!结果在我的主程序的“用数据做东西”部分我最终增加了指针,所以删除显然不起作用!哦!

所以我正在编译一个共享库,它的功能类似于这个(超级简化视图),这个库也是我的——所以我知道数据是如何分配的:

// inside library

void* getData(int size) { // with other parameters

    UINT8* data = new UINT8[size];  // where typedef uint8_t  UINT8; for gcc

    // do a socket read, where data is the buffer
    blockingRead (someSocket, data, propertySize); 

    return (void*) data;
}

它必须返回一个 void 指针,因为数据可能是一个结构体(因此可以直接转换为结构体)。

问题是,我在我的主程序中使用了这个指针,我想在完成后删除它。如果我在我的主程序中这样做:

// inside main program
char* data = (char*) Library::getData(5);
// do stuff with data

delete[] data; // crashes with:
// *** glibc detected *** core: free(): invalid pointer: 0x00002aaab007bca4 ***

我想也许我应该在共享库中删除它:

// inside library

void disposeData(void* data) {  // call this from main program
    delete[] (UINT8*) data; // cast it back to the original type of pointer
}

但我仍然遇到同样的崩溃!如果我不删除,一切都会正常运行,但我不希望整个程序出现不必要的内存泄漏。

我可能在某个地方做了一些愚蠢的事情——请帮我找出我的方法中的错误!

编辑:正如 cmets 中所指出的,上面的代码似乎有效——我将不得不看看是什么具体导致了我的代码中的错误。

【问题讨论】:

  • 我认为您需要创建一个最小示例来展示您的问题。我已经用 g++ 尝试过你的代码,它运行得很好......没有崩溃。
  • 谢谢诺亚!嗯,我想还有更多...我会调查
  • 您的问题可能出在// do stuff with data 部分,所以也粘贴一下。您没有删除与 Library::getData(5) 返回相同的指针(可能是因为缓冲区溢出,或者您在某处为 data 分配了其他内容)
  • 您是否已经删除了数据并且您正在尝试再次删除它?
  • 谢谢大家!事实证明 nos 是对的,我在“用数据做事”部分增加了指针!啊,对不起,伙计们哈哈

标签: c++ shared-libraries delete-operator


【解决方案1】:

您是否尝试过使用valgrind?使用 valgrind 将帮助您查明范围广泛的内存管理错误,这些错误可能是导致问题的原因。您看到的错误看起来像是堆损坏(正如@nos 所说,可能在 do stuff 部分中),或者您实际上并没有释放您最初分配的同一个对象。

【讨论】:

    【解决方案2】:

    如果库为您提供分配的指针,它应该解释如何释放它们。它可以提供自己的释放功能。除非您拥有库的源代码并且可以验证它是否使用new[] 创建指针,否则您无法确定它是如何分配内存的。您的崩溃很可能是因为您的释放器与其分配器不匹配。

    【讨论】:

      【解决方案3】:

      如何改用基于 RAII 的设计,例如智能指针? Boost 智能指针设计得非常好。

      【讨论】:

        【解决方案4】:

        我敢打赌,当你提到“演员表”时,你正在做类似的事情:

        #include <stdio.h>
        
        class B { int x; };
        
        class C { int y; };
        
        class A : public B, public C { };
        
        void* getData()
        {
            A* a = new A();
            printf("%p\n", a);
            C* c = a;
            printf("%p\n", c);
            return c;
        }
        
        void deleteData(void* x)
        {
            // delete (A*)x; // incorrect; causes crash
            delete (A*)(C*)x; // correct
        }
        
        int main()
        {
            void* x = getData();
            deleteData(x);
            return 0;
        }
        

        请注意,编译器可能会在你背后将看似无辜的强制转换转换为指针运算。

        【讨论】:

          猜你喜欢
          • 2021-11-07
          • 1970-01-01
          • 2012-10-26
          • 1970-01-01
          • 2019-01-21
          • 1970-01-01
          • 1970-01-01
          • 2015-01-03
          • 1970-01-01
          相关资源
          最近更新 更多