C++ dll堆内存分配问题

标签 c++ linux dll shared-libraries

从此link ,我知道我们(应用程序)应该总是不要从 dll 中删除一个堆内存分配,因为堆内存管理器不同。

我有几个问题:

1.) .so 文件(Linux)怎么样,是不是同样的情况?

2.) 无论如何要确保应用程序和库(.dll 和 .so)使用相同的堆内存管理器或使用相同的堆内存部分?所以我们可以分别删除和新建(new at .dll/.so,delete at application)。

谢谢你。

最佳答案

1.) How about .so file (Linux), is it the same case ?



是的,使用与最终链接的程序不同的标准 C++ 库实现构建的库可能会以稍微不同的方式进行分配。 g++libstdc++clang++libc++ 是两种不同实现的示例。它们可能 100% 兼容 ABI - 但第三个未知库可能不是。

2.) Is there anyway to make sure that application and library(.dll and .so) are using same heap memory manager or using same heap memory section ? So we can delete and new separately (new at .dll/.so, delete at application ).



不,编译到库中的是库将使用的内容,除非有办法在加载库时对其进行初始化,告诉它使用特定的堆管理器。

Please explain in details. I wish to know for .so (Linux), is it using only one heap manager for both application and .so (library). Let's said, my application compiled by compiler version A, while my .so complied by compiler version B, is it still ok ?



由于上面提到的原因,不,你不能确定。由于您是库的创建者,因此您可以创建 API,以便将库中类型的 newdelete 内存分配/释放委托(delegate)给编译到库中的成员函数,而这些函数又会执行真正的分配/释放(在 operator new, operator new[] 中描述
operator delete, operator delete[] )。然后,指向您的类型对象的指针可以被 new 编辑并在库和应用程序之间传递,并且在任一侧都是 delete d。

这是一个(不完整的)示例,说明如何使用特定于类的分配函数:void* T::operator new(std::size_t count);
和一个特定于类的常用释放函数:void T::operator delete(void* ptr);
它包含 foo.hppfoo.cpp 用于创建 libfoo.so (或 libfoo.a )和使用该库的程序的代码。

foo.hpp
#pragma once

#include <new>

class Foo {
public:
    // The "usual" part of your class definition:
    Foo(int x);
    ~Foo();

    // This part does NOT get compiled into your library.
    // It'll only be used by users of your library:
#ifndef BUILDING_LIB
    // Note: operator new and delete are static by default

    // single object allocation/deallocation:
    void* operator new(std::size_t /* byte_count */) { return Alloc(); }
    void operator delete(void* addr) { Free(addr); }

    // array allocation/deallocation:
    // TODO: operator new[] and delete[]
#endif
private:
    int value;

    // the functions really doing the memory management
    static void* Alloc();
    static void Free(void* p);
};

foo.cpp
// Define BUILDING_LIB to disable the proxy operator new/delete functions when building
// the library.
#define BUILDING_LIB
#include "foo.hpp"

#include <cstdlib> // std::aligned_alloc
#include <iostream>

Foo::Foo(int x) : value(x) {
    std::cout << "Foo:Foo(" << value << ")\n";
}

Foo::~Foo() {
    std::cout << "Foo:~Foo() " << value << "\n";
}

void* Foo::Alloc() {
    void* addr = std::aligned_alloc(alignof(Foo), sizeof(Foo));
    std::cout << "Alloc() " << sizeof(Foo) << "\t@ " << addr << '\n';
    return addr;
}

void Foo::Free(void* addr) {
    std::cout << "Free()\t\t@ " << addr << '\n';
    std::free(addr);
}

使用lib.cpp
#include "foo.hpp"

#include <memory>

int main() {
    auto a = std::make_unique<Foo>(123); // heap allocation

    // An automatic variable will use the applications memory manager and will not
    // use Alloc/Free.
    Foo b(456);
}

可能的输出:
Alloc() 4       @ 0x1af7eb0
Foo:Foo(123)
Foo:Foo(456)
Foo:~Foo() 456
Foo:~Foo() 123
Free()          @ 0x1af7eb0

关于C++ dll堆内存分配问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59542254/

相关文章:

c++ - 删除了隐式声明的复制赋值运算符

c++ - 在 C++ 中将输入直接输入到 vector 中

c++ - SublimeLinter clang - 找不到基本标题

regex - 使用 grep 或 sed 的正则表达式不起作用

linux - 用字符串更改数字的 Shell 脚本

c# - System.DllNotFoundException : Unable to load DLL. 开发机器没有错误但目标机器有错误

c++ - 抽象基类中私有(private)虚函数的可见性

php - 升级后的 PHP 现在 apache 不再执行 php 文件

c++ - 在运行时加载 opengl/directx API 函数

C++ Qt MingW 错误重新定位 0xc 地址在 rdata 节中