gpt4 book ai didi

C++ dll堆内存分配问题

转载 作者:行者123 更新时间:2023-12-04 13:21:01 26 4
gpt4 key购买 nike

从此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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com