C++ 无符号字符数组的自动指针?
我需要一个像std::auto_ptr这样的类,用于分配新[]的无符号字符*数组。但是auto_ptr只调用delete而不调用delete[],所以我不能使用它 我还需要一个创建并返回数组的函数。我在类ArrayDeleter中实现了我自己的实现,我在本例中使用它:C++ 无符号字符数组的自动指针?,c++,C++,我需要一个像std::auto_ptr这样的类,用于分配新[]的无符号字符*数组。但是auto_ptr只调用delete而不调用delete[],所以我不能使用它 我还需要一个创建并返回数组的函数。我在类ArrayDeleter中实现了我自己的实现,我在本例中使用它: #include <Utils/ArrayDeleter.hxx> typedef Utils::ArrayDeleter<unsigned char> Bytes; void f() { // C
#include <Utils/ArrayDeleter.hxx>
typedef Utils::ArrayDeleter<unsigned char> Bytes;
void f()
{
// Create array with new
unsigned char* xBytes = new unsigned char[10];
// pass array to constructor of ArrayDeleter and
// wrap it into auto_ptr
return std::auto_ptr<Bytes>(new Bytes(xBytes));
}
...
// usage of return value
{
auto_ptr<Bytes> xBytes(f());
}// unsigned char* is destroyed with delete[] in destructor of ArrayDeleter
#包括
typedef Utils::ArrayDeleter字节;
void f()
{
//使用新的
无符号字符*xBytes=新的无符号字符[10];
//将数组传递给ArrayDeleter的构造函数并
//将其包装到自动ptr中
返回std::auto_ptr(新字节(xBytes));
}
...
//返回值的使用
{
自动字节(f());
}//未签名字符*在ArrayDeleter的析构函数中用delete[]销毁
有没有更优雅的方法来解决这个问题?(即使使用另一个“流行”的库)Boost有多种自动指针,包括用于数组的指针。您是否考虑过std::vector是否足够?向量在内存中保证是连续的,如果您通过
reserve()
或resize()
提前知道大小并分配内存,那么内存中的位置不会改变。使用std::basic_string
怎么样?或者可能是std::vector
然后我必须调用一个以无符号字符*为参数的方法
std::向量向量向量机;
.
.
.
遗留_函数(&vec[0],vec.size());
delete[]
相当于调用delete
。所以使用std::auto_ptr
没有问题
ArrayDeleter
的一个实例,该实例封装了指向所分配数组的指针- 表现更差。堆操作很繁重。此外,它们还具有显著的内存开销
- 访问速度较慢。要通过
访问数组元素,编译器将生成两个间接指令:一个用于获取std::auto_ptr
对象,另一个用于访问元素。 简单地说:字节
有一个指向std::auto_ptr
字节的指针,该对象有一个指向数组的指针
- 错误/异常一致性更差。想象一下,如果
未能分配操作符new
对象会发生什么。它将生成一个可以处理的异常。但此时您已经分配了数组。这一分配将丢失字节
std::auto\u ptr
。这应该可以完成工作。但是,您应该使用编译器检查它std::auto_ptr
我看了一下boost,我认为scoped_数组可以做到这一点。Thanks@Gianluca:你为什么不使用vector?@GMan:当然,现在我觉得这是个更好的主意。然后,ThanksI必须调用以unsigned char*为参数的方法。有没有一种方法可以从你建议的容器中取用它?basic_string的方法data()可以吗?您可以使用std::string'.c_str()'方法,这将返回一个以null结尾的字符*。在动态分配的数组上调用
delete
始终是未定义的行为,即使它在您尝试的所有编译器上似乎总是对您有效。delete[]并不等同于调用delete,即使是豆荚。请参阅标准中的18.6.1.2(数组形式):“void操作符delete[](void*ptr)throw();…Requires:ptr…应为先前调用操作符new[](std::size_t)或操作符new[](std::size_t,const std::nothrow_t&)返回的值。”这正是我编写“您应该使用编译器检查它”的原因严格地说,你是对的。标准说这是一种未定义的行为。我说了实际发生的事情。至少在MSVC编译器上。应该使用“delete[]”而不是“delete”的原因并不是因为我们需要知道应该释放多少内存-根据这个参数,您还必须将内存大小传递给“free”函数。原因是,当你使用“DEL[(])”时,编译器除了释放内存之外,还生成对对象的调用。@ Valdo:但是人们想要编程C++,而不是它的特定变体。依赖未定义的行为是不好的。@Valdo这不是真的:当您使用delete[]时,您以正确的形式释放了正确数量的内存。我不知道,你为什么建议依赖(某个版本的)编译器的古怪行为。
std::vector<unsigned char> vec;
.
.
.
legacy_function(&vec[0], vec.size());