C ++释放共享库中动态分配的内存导致崩溃

Posted

技术标签:

【中文标题】C ++释放共享库中动态分配的内存导致崩溃【英文标题】:C++ freeing dynamically allocated memory in shared library causing crash 【发布时间】:2022-01-12 18:30:46 【问题描述】:

我有一个共享库 mod.so,它有一个函数 getptr 来返回指向动态分配的内存的指针。它还有一个函数 Unload,它释放分配的内存。 主程序在运行时加载这个共享库,并从 getptr 获取指针 函数,但是当调用 Unload 函数时,它给了我分段错误。

ma​​in.cpp

    #include <iostream>
#include <dlfcn.h>
using namespace std;
int main()

  void* module = dlopen("mod.so",RTLD_LAZY);
  typedef int*(*func)();
  typedef void(*func1)();
  func f = (func)dlsym(module,"getptr");
  func1 b = (func1)dlsym(module,"Unload");
  int* p = f();
  b();

mod.cpp

    #include <iostream>
#include <vector>
using namespace std;
vector<int*> allocated;
extern "C"

  int* getptr()
  
    int* p = new int;
    *p = 1024;
    allocated.push_back(p);
    return p;
  
  void Unload()
  
    for(auto e: allocated)
      delete e;
  

mod.cpp 编译为:

g++ -shared mod.cpp -o mod.so -fPIC

【问题讨论】:

int* Unload() -- 当您应该返回 int* 时,您没有返回值 -- 未定义的行为。另外,你的编译器应该已经警告过你了。 不,这不是程序崩溃的问题,即使我使用 void Unload() 这是否能解决您的问题无关紧要——代码错误,如果不进行更改,您将无法更进一步。 Unload() 中,您不调用allocated.clear()。如果你多次使用Unload() 并由getptr() 交错,你可能会得到双释放(或空解引用)错误,除非你去掉你调用delete 的指针。如果你不多次使用Unload(),那为什么这段代码不在析构函数中呢?为什么要使用原始指针? vector&lt;unique_ptr&lt;int&gt;&gt; allocated; ...; allocated.push_back(make_unique&lt;int&gt;(1024)) 怎么样?这会自动处理您的释放。为什么要手动分配ints?为什么不vector&lt;int&gt; v; ...; return &amp;v.emplace_back(1024); 在资源及其分配方面,以pairs 的形式创建函数始终是一个不错的设计选择:一个用于创建或分配,一个用于销毁或释放。跨度> 【参考方案1】:

dlopen("mod.so",RTLD_LAZY) 返回 NULL。试试这个:

void* module = dlopen("./mod.so",RTLD_LAZY);
if (!module) 
    fprintf(stderr, "error in dlopen: %s\n", dlerror());
    return 1;

编辑:通过此修改,您的代码在 Linux/amd64 上使用 gcc-10.2 为我工作

请注意,如果您调用 Unload 两次, 会导致严重问题。可能的修复:

#include <iostream>
#include <vector>
using namespace std;
vector<int*> *allocated= NULL;
extern "C"

  int* getptr()
  
    if (!allocated) allocated= new vector<int *>();
    int* p = new int;
    *p = 1024;
    allocated->push_back(p);
    return p;
  
  void Unload()
  
    if (allocated) 
      for(auto e: *allocated)
        delete e;
      delete allocated;
      allocated= NULL;
    
  

【讨论】:

不,我已经检查过 dlopen() 不返回 NULL 请编辑您的原始帖子并包含显示问题的实际minimal reproducible example。 (例如,如果您使用了一些 LD_LIBRARY_PATH env.var。请说明。)

以上是关于C ++释放共享库中动态分配的内存导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

动态内存分配

怎么查看动态分配内存空间的大小(c语言)。

c语言中啥是动态分配内存?

C++程序的内存分区,为什么要使用动态内存,动态内存的分配使用释放

c语言分配内存方式都有哪些

零基础学C语言知识总结十一:动态内存分配!