shared_ptr<T[]>包装动态数组时出现问题
Problems with shared_ptr<T[]> wrapping a dynamic array
我想用std::shared_ptr
替换类中的一些原始指针,这样在创建该类的副本时就不必担心了。但是原始指针指向一个动态数组。当您为shared_ptr提供一个自定义的deleter时,可以将其与动态数组一起使用;g.CCD_ 2。
但是,当我尝试为该字段分配一个新值时,即使在构造时,我也会收到一个大错误列表。
这里有一个最小的代码示例:
#include <memory>
#include <cstddef>
using namespace std;
template<typename T> shared_ptr<T[]> make_shared_array(size_t size)
{
return shared_ptr<T[]>(new T[size], default_delete<T[]>());
}
struct Foo
{
shared_ptr<char[]> field;
};
int main()
{
Foo a;
// This line produces the error.
a.field = make_shared_array<char>(256);
return 0;
}
注意:是的,我知道我可以/应该vector
而不是动态数组。但他们的表现并不相同。我做了一些繁重的图像处理,数组保存了像素。在低于VGA分辨率的情况下,处理时间从8增加到11;s.那真是太多了。
更新:我当然可以在这里提供错误。我只是不知道我是否应该把问题描述弄得一团糟。但它是:
C: \Program Files(x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\memory(754):错误C2664:"std::_Ptr_base<_Ty>::_Reset0":无法将参数1从"char"转换为"char()[]"
与
[
_Ty=char[]
]
指向的类型是不相关的;转换需要reinterpret_cast、C样式强制转换或函数样式强制转换
C: \Program Files(x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\memory(723):请参阅对函数模板实例化的引用'void std::shared_ptr<_Ty>::_Resetp0<_Ux>(_Ux*,std::_Ref_count_base*)'正在编译
与
[
_Ty=char[],
_Ux=字符
]
C: \Program Files(x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\memory(723):请参阅对函数模板实例化的引用'void std::shared_ptr<_Ty>::_Resetp0<_Ux>(_Ux*,std::_Ref_count_base*)'正在编译
与
[
_Ty=char[],
_Ux=字符
]
C: \Program Files(x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\memory(494):请参阅对函数模板实例化的引用'void std::shared_ptr<_Ty>::_Resetp<_Ux,_Dx>(_Ux*,_Dx)'正在编译
与
[
_Ty=char[],
_Ux=字符,
_Dx=std::default_delete
]
C: \Program Files(x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\memory(494):请参阅对函数模板实例化的引用'void std::shared_ptr<_Ty>::_Resetp<_Ux,_Dx>(_Ux*,_Dx)'正在编译
与
[
_Ty=char[],
_Ux=字符,
_Dx=std::default_delete
]
problem.cpp(9):请参阅对函数模板实例化的引用"std::shared_ptr<_Ty>::shared_ptr>(_Ux*,_Dx)'正在编译
与
[
_Ty=char[],
T=字符,
_Ux=字符,
_Dx=std::default_delete
]
problem.cpp(9):请参阅对函数模板实例化的引用"std::shared_ptr<_Ty>::shared_ptr>(_Ux*,_Dx)'正在编译
与
[
_Ty=char[],
T=字符,
_Ux=字符,
_Dx=std::default_delete
]
problem.cpp(21):请参阅对函数模板实例化的引用"std::shared_ptr<_Ty>make_shared_array(size_t)'正在编译
与
[
_Ty=char[]
]
您建议的解决方案是可能的,但您将失去数组的大小:
#include <memory>
#include <cstddef>
using namespace std;
template<typename T> shared_ptr<T> make_shared_array(size_t size)
{
return shared_ptr<T>(new T[size], default_delete<T[]>());
}
struct Foo
{
shared_ptr<char> field;
};
int main()
{
Foo a;
a.field = make_shared_array<char>(256);
return 0;
}
我在这里所做的是让数组衰减为一个指针。只要deleter是数组deleter,它的行为就应该正确。
为了防止这种大小损失,并且如果您不能按照建议使用boost::shared_array,我建议将这些信息封装在您自己的shared_array类中。
如果您坚持不应该使用std::vector
,Boost有一个boost::shared_array
,它可以作为智能指针来管理动态分配的对象数组。
shared_ptr
不是为处理数组而设计的。既然shared_array
可用,为什么要尝试在数组上使用shared_ptr
?
如果指定了deleter,则在模板参数中不使用T[]
。只需将T[]
更改为T
:
template <typename T> shared_ptr<T> make_shared_array(size_t size)
{
return shared_ptr<T>(new T[size], default_delete<T[]>());
}
struct Foo
{
shared_ptr<char> field;
};
std::unique_ptr
专门用于数组类型,因此您可以将T[]
与它一起使用,它会知道它仍然只是存储一个T*
。std::shared_ptr
不是以这种方式专门化的,因此shared_ptr<T[]>
将尝试存储指向数组T(*)[]
的指针,这与C++中围绕原始数组的约定不太好地配合使用。更不用说未知大小的数组是不完整类型,shared_ptr
最终需要一个完整类型。
您提到知道std::vector
应该是一个更好的解决方案,但性能不太好。它应该表现得很好,你最好弄清楚为什么它没有。
- std::向量与传递值的动态数组
- 将数组动态分配到具有指针参数的函数中
- 我可以以某种方式使我的矢量/数组动态更改装置数量吗?
- 使用 new: "potentially uninitialized pointer"将对象数组动态分配给指针
- 为什么C 没有方便的方式来为多维数组动态分配内存
- 如何制作具有动态大小的数组?动态数组的一般用法(可能还有指针)
- c++中的数组动态内存分配
- 多维数组动态分配的内存图
- 如何在 c++ 中使用 2-D 固定数组为 4-D 数组动态分配内存
- C++ 我在数组/动态内存方面遇到了一些问题
- C++ 中从数组动态强制转换
- C++中高维数组动态内存分配的正确方法.
- 从 C++ 结构中包含的指针数组动态分配和访问内存
- 对象数组动态内存分配
- 为二维数组动态分配内存时出错
- 如何将2d数组动态分配给结构
- 为结构数组c++动态分配内存
- 将数组动态添加到多维数组
- 类中的类数组-动态数组(c++)有问题
- 分配对象数组动态冻结