C++ 无符号字符数组的自动指针?

C++ 无符号字符数组的自动指针?,c++,C++,我需要一个像std::auto_ptr这样的类,用于分配新[]的无符号字符*数组。但是auto_ptr只调用delete而不调用delete[],所以我不能使用它 我还需要一个创建并返回数组的函数。我在类ArrayDeleter中实现了我自己的实现,我在本例中使用它: #include <Utils/ArrayDeleter.hxx> typedef Utils::ArrayDeleter<unsigned char> Bytes; void f() { // C

我需要一个像std::auto_ptr这样的类,用于分配新[]的无符号字符*数组。但是auto_ptr只调用delete而不调用delete[],所以我不能使用它

我还需要一个创建并返回数组的函数。我在类ArrayDeleter中实现了我自己的实现,我在本例中使用它:

#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());
> p>您讨论的是一个 int >代码>,不是具有析构函数的复杂C++类型。 对于这样的数组,调用
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());