包含分配指针的结构的向量无法进行析构函数



在我的项目中,我使用一个类进行分页内存分配。这个类使用一个结构来存储它的所有分配:

enum PageStatus : uint_fast8_t {    //!< possible use stati of an allocated page
PAGE_STATUS_INVALID     = 0b00,
PAGE_STATUS_FREE        = 0b01, //!< the page is free
PAGE_STATUS_USED        = 0b10, //!< the page is (partially) used
};
struct PhysicalPage {    //!< represents a page that has been allocated
char* pData;         //!< pointer to the allocation
PageStatus status;   //!< status of the allocation
};

这些PhysicalPage被存储在向量std::vector<PhysicalPage> physicalAllocations {};中。在运行时,页面会被添加到向量中,有些页面可能会被删除。在移除过程中,弹出最后一个元素,并使用delete page.pData返回内存。然而,当分配器类到达寿命终点并从堆栈中被释放时,就会出现问题。当调用pyhsicalAllocations的向量析构函数时,它不仅试图析构函数本身的元素,还试图析构因子保留的内存(当大小发生变化时,向量会将其作为缓冲区(。这会导致无效的内存指针被删除,从而停止程序执行:

double free or corruption (!prev)
Signal: SIGABRT (Aborted)

可能还值得一提的是,分配是在比页面大的块中进行的,这意味着每x个指针中只有一个是有效的分配。所有其他指针只是与实际内存位置的偏移量。

为了防止错误发生,我尝试了:

手动删除(由于分块分配,这有点过于复杂(

for (size_t i = physicalAllocations.size(); 0 < i; i -= 1 << allocationChunkSize) {
delete physicalAllocations[i - (1 << allocationChunkSize)].pData;
for (size_t a = 0; a < 1 << allocationChunkSize; a++)
physicalAllocations.pop_back();
}

清除矢量

physicalAllocations.clear();

交换为清除向量

std::vector<PhysicalPage>(0).swap(physicalAllocations);

其中没有一个起作用。

我想承认,我已经解决这个问题很久了,非常感谢你的帮助。谢谢

std::shared_ptr<char[]> pData及其别名构造函数(8(可能会有所帮助。(这甚至可能允许去掉PageStatus(。

它看起来像:

constexpr std::size_t page_size = 6;
struct PhysicalPage {
std::shared_ptr<char[]> pData;
};
int main()
{
std::vector<PhysicalPage> pages;
{
std::shared_ptr<char[]> big_alloc = std::unique_ptr<char[]>(new char[42]{"hello world. 4 8 15 16 23 42"});
for (std::size_t i = 0; i != 42 / page_size; ++i) {
pages.push_back(PhysicalPage{std::shared_ptr<char[]>{big_alloc, big_alloc.get() + i * page_size}});
}
}
pages.erase(pages.begin());
pages.erase(pages.begin() + 2);    
for (auto& p : pages) {
std::cout << std::string_view(p.pData.get(), page_size) << std::endl;
}
}

演示

最新更新