【问题标题】:Using std::unique_ptr on Object whose Size is Determined at Run Time对大小在运行时确定的对象使用 std::unique_ptr
【发布时间】:2014-03-22 06:19:08
【问题描述】:

我有以下代码:

Gdiplus::Image image(filename.c_str());
UINT size = image.GetPropertyItemSize(PropertyTagExifDTOrig);
Gdiplus::PropertyItem* propertyItem = (Gdiplus::PropertyItem*)malloc(size);

问题在于此之后的代码基于几个不同的条件进行了分支。所以我想使用std::unique_ptr之类的东西来确保最后一行的指针被删除,无论我的代码在哪里分支。

但是,std::unique_ptr 似乎无法在此处轻松实现。好像需要固定大小的类型,不支持自定义大小。

这是对的吗?这里有什么好办法实现自动指针吗?

【问题讨论】:

  • 当代码是 C++ 时,你为什么使用malloc
  • @EdHeal:有点好奇,这样做有什么问题吗?
  • @EdHeal: (1) 你错了,malloc 的 C++ 替代品是 not new。它是operator new(size_t),它也not 调用构造函数。 (2) 啊?什么是“它”,为什么这很重要? (3) 再次,C++ 替代方案存在调用operator delete 的问题;使用 malloc 而不是 operator new 不会改变任何东西。 (4) 好的,当然,这是我猜的原因之一。
  • @EdHeal:我认为您可能误解了此处 OP 的目标可能是分配比对象本身所需的空间更大的空间。 new T 无法实现这一点;您必须将operator newplacement new 结合使用。 OP 只是将operator new 替换为malloc,这在可读性/正确性方面非常好;它只是有点不习惯。
  • @EdHeal:我的意思是在 C++ 中使用malloc 分配内存 没有任何问题。当然,使用它来构造一个新对象是有问题的,但是使用malloc 本身并不是问题——这是完全使用错误函数的问题。切换到 C++ 对应项(即operator new)将不再正确,因此说malloc 是问题所在是错误的。

标签: c++ stl std unique-ptr


【解决方案1】:

std::unique_ptr 支持自定义删除器。由于您使用malloc 进行分配,因此您可以使用free

std::unique_ptr<Gdiplus::PropertyItem, void (*)(void*)> propertyItem{
    (Gdiplus::PropertyItem*) std::malloc(size), &std::free};

如果您希望避免传递删除器,您可以创建一个结构来为您执行删除操作:

struct FreeDeleter {
  void operator()(void* p) {
    std::free(p);
  }
};

std::unique_ptr<Gdiplus::PropertyItem, FreeDeleter> propertyItem{
    (Gdiplus::PropertyItem*) std::malloc(size)};

【讨论】:

  • 请不要鼓励在 C++ 代码中使用malloc
  • @EdHeal:如果您发现没有malloc() 的好方法,请分享。
【解决方案2】:
std::unique_ptr<Gdiplus::PropertyItem[]> pitem(new Gdiplus::PropertyItem[size]);

std::unique_ptr<Gdiplus::PropertyItem[]> pitem = std::make_unique<Gdiplus::PropertyItem[]>(size);

【讨论】:

    猜你喜欢
    • 2016-10-05
    • 2014-03-16
    • 1970-01-01
    • 2017-07-29
    • 2012-08-24
    • 2011-04-26
    • 2014-01-11
    • 1970-01-01
    • 2012-12-11
    相关资源
    最近更新 更多