C++ 在运行时确定大小的对象上使用std::unique_ptr

C++ 在运行时确定大小的对象上使用std::unique_ptr,c++,stl,std,unique-ptr,C++,Stl,Std,Unique Ptr,我有以下代码: Gdiplus::Image image(filename.c_str()); UINT size = image.GetPropertyItemSize(PropertyTagExifDTOrig); Gdiplus::PropertyItem* propertyItem = (Gdiplus::PropertyItem*)malloc(size); 问题是,在此之后的代码会根据几个不同的条件进行分支。因此,我想使用类似于std::unique\u ptr的方法来确保最后一行

我有以下代码:

Gdiplus::Image image(filename.c_str());
UINT size = image.GetPropertyItemSize(PropertyTagExifDTOrig);
Gdiplus::PropertyItem* propertyItem = (Gdiplus::PropertyItem*)malloc(size);
问题是,在此之后的代码会根据几个不同的条件进行分支。因此,我想使用类似于
std::unique\u ptr
的方法来确保最后一行上的指针被删除,无论我的代码分支在哪里

然而,
std::unique\u ptr
似乎不容易在这里实现。它似乎需要固定大小的类型,不支持自定义大小


是这样吗?这里有没有实现自动指针的好方法?

std::unique\u ptr
支持自定义删除程序。由于您使用的是
malloc
,因此可以使用
免费

std::unique_ptr<Gdiplus::PropertyItem, void (*)(void*)> propertyItem{
    (Gdiplus::PropertyItem*) std::malloc(size), &std::free};
std::唯一的\u ptr属性项目{
(Gdiplus::PropertyItem*)std::malloc(大小),&std::free};
如果您希望避免传递删除程序,则可以创建一个执行删除操作的结构:

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

std::unique_ptr<Gdiplus::PropertyItem, FreeDeleter> propertyItem{
    (Gdiplus::PropertyItem*) std::malloc(size)};
struct FreeDeleter{
void运算符()(void*p){
std::游离(p);
}
};
std::唯一的\u ptr属性项目{
(Gdiplus::PropertyItem*)std::malloc(size)};
std::unique_ptr pitem(新的Gdiplus::PropertyItem[size]);
std::unique_ptr pitem=std::make_unique(尺寸);

<代码>为什么当代码为C++时?你使用“代码> MalC++ <代码>:有点奇怪,做什么有什么不对吗?”EdCurr:(1)你错了,C++的替代代码< MalOC/<代码>不是<代码>新< /C>。它是
操作符new(size\u t)
,它也不调用构造函数。(2) 嗯?什么是“它”,为什么这很重要?(3)C++替代方案中存在调用<代码>操作符删除>代码>的问题;使用
malloc
而不是
operator new
不会改变任何东西。(4) 好的,当然,这是我想的一个原因。@EdHeal:我想你可能误解了OP的目标是分配比对象本身所需的空间更大的空间。使用
新T
无法实现这一点;您必须将
运算符new
与placement
new
结合使用。OP简单地用
malloc
替换了
operator new
,这在可读性/正确性方面非常好;这只是一点简单的。“我说的是,使用<代码> MaloC < /Cuff>在C++中分配内存没有什么错。当然,使用它来构造一个新对象是有问题的,但使用
malloc
本身并没有问题,而是完全使用了错误的函数。切换到C++对应(即<代码>运算符new <代码>)将不再正确,所以错误地说<代码> MalOC 是问题。请不要鼓励在C++代码中使用<代码> MalOC 。@ EdCurry:如果你看到一个很好的方法来实现这个,而不是<代码> MalCube()/<代码>,请分享。
std::unique_ptr<Gdiplus::PropertyItem[]> pitem(new Gdiplus::PropertyItem[size]);

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