【问题标题】:Can I create an array of auto_ptr?我可以创建一个 auto_ptr 数组吗?
【发布时间】:2013-08-22 07:14:13
【问题描述】:

我有一个基类,它被多个派生类继承。我想创建基类指针的自动指针数组。当我初始化那些自动指针时,我得到了一些编译时错误,然后我尝试这样做

std::auto_ptr<base>pbase[3];

std::auto_ptr<base> b1(new derived1());
std::auto_ptr<base> b2(new derived2());
std::suto_ptr<base> b3(new derived3());

pbase[0] = b1;
pbase[1] = b2;
pbase[2] = b3;

它工作正常,我修复了内存泄漏问题,而我是一个窗口,我不使用 valgrind,我使用 boost 框架来解决泄漏问题。

编译错误:

class A{
 public:
  std::auto_ptr<base>pbase[2];
}

在 A.cpp 文件中

A::A():pbase[0](new derived1()), pbase[1](new derived2()){
}

我收到错误C2059:syntax error : '['

【问题讨论】:

  • 请也发布错误信息。
  • 你有虚拟析构函数吗?此外,请使用 unique_ptr 和 shared_ptr 而不是 auto_ptr。考虑使用 std::vector 来存储您的指针。
  • auto_ptr 因其怪异的复制行为而被弃用。考虑切换到std::unique_ptr
  • 不是同一个问题,所以不投票结束重复,而是this has useful answers
  • 还有一件事;我想这只是一个错字,但您正在访问pbase[3],它会调用未定义的行为

标签: c++ visual-studio-2010 visual-c++ auto-ptr


【解决方案1】:

std::auto_ptr 自 C++11 起已弃用,不应使用,因为它具有奇怪的复制行为:

std::auto_ptr<int> a(new int(1));
std::auto_ptr<int> b = a; // invalidates a!

std::unique_ptr 现在彻底解决了它试图实现的目标。在引入移动语义和右值引用之前,这是不可能的。

但是,这似乎不是这里的问题。从您的示例中,您可能会因为调用未定义的行为而泄漏内存:

pbase[3] = b3; // pbase is std::auto_ptr<base>[3]
               // pbase[0] - pbase[2] are valid indexes

事实上,当I fix that problem 并在结果上运行valgrind --leak-check=full ./auto_ptr_app 时,它告诉我不可能有泄漏。

【讨论】:

  • 一个典型的未定义行为示例,如果您调用未定义行为,您可能有内存泄漏......或几乎任何其他!
  • @MatthieuM。确切地。这就是为什么我选择措辞有可能 - 任何事情都是。
  • @user1808932 所以索引越界不是导致您的问题吗?除此之外,我只能想到多态性的奇怪问题或完全不同的东西,这两个问题在你的例子中并不明显
  • 我已经修复了泄漏问题,这是我的愚蠢,而我已经更新了编译时错误。
【解决方案2】:

我刚刚对以下代码段运行了两次 valgrind 测试:

第一次运行:

class Foo
{
public:
    Foo(){}
    virtual ~Foo(){}
};

class Bar: public Foo
{
public:
    Bar(){}
    virtual ~Bar(){}
};

int main(int argc, char** argv) 
{
   std::auto_ptr<Foo>arr[3];

   std::auto_ptr<Foo> one(new Bar());
   std::auto_ptr<Foo> two(new Bar());
   std::auto_ptr<Foo> three(new Bar());

   arr[0] = one;
   arr[1] = two;
   arr[2] = three;
   return 0;
} 

第二次运行:

class Foo
{
public:
    Foo(){}
    virtual ~Foo(){}
};

class Bar: public Foo
{
public:
    Bar(){}
    virtual ~Bar(){}
};

int main(int argc, char** argv) 
{
   std::auto_ptr<Foo> one(new Bar());
   return 0;
}

虽然 Valgrind 确实在这两种情况下都显示了可能的内存泄漏,但它显示的警告完全相同对于它们来说是相同的(相同数量的警告、相同的警告文本、相同的堆栈),指向某个地方在我的代码之外到 linux .so 文件。因此,我们可以假设您使用auto_ptr 数组的方式很好。但是,正如 cmets 中所述,由于 C++0x(这是当前的 C++ 标准),auto_ptr 被认为已弃用,因为它具有奇怪的复制行为(您可以找到更多信息,例如,in this article)。建议改用std::unique_ptr

现在,如果您的代码中有一些额外的内存泄漏,那么很可能是由于您自己的类而发生的。不幸的是,您没有将它们包含在问题中,因此我们无法确定。在这种情况下,您应该检查类的构造函数和析构函数是否存在内存泄漏,或者至少向我们展示您的类。另一个原因可能是您在代码中的数组索引中的拼写错误(pbase[3],已用完键)。

【讨论】:

  • 没有泄漏,我已经解决了这个问题,这是我的错。 :)
【解决方案3】:

您的问题可能与auto_ptr 无关,尽管它已被弃用,您应该改用unique_ptrshared_ptr(如果您的编译器不支持C++11,请使用boost::shared_ptr)。似乎泄漏在您的类实现中。检查base 是否具有虚拟析构函数,因为如果您想多态地使用该类,则需要它。还要检查基类和派生类的任何成员并删除您分配的所有内容。

【讨论】:

    猜你喜欢
    • 2020-08-10
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多