Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I create an array of auto_ptr?

I have a base class, which is inherited by multiple derived classes. i want to create array of autopointer of baseClass pointer. when i initialise those autopointer i get some compile time error, then i tried to do like that way

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;

it works fine, i fixed the memory leak issue, while i m one windows, i don't use valgrind, i use boost framework for leaks.

for compile error:

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

in A.cpp file

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

i got error C2059:syntax error : '['

like image 681
user1808932 Avatar asked Jan 12 '23 14:01

user1808932


2 Answers

std::auto_ptr is deprecated since C++11 and should not be used because of its weird copying behavior:

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

What it tried to achieve is now solved cleanly by std::unique_ptr. Before the introduction of move semantics and rvalue references this was not possible.

However, this does not seem to be the problem here. From your example it is possible that you are leaking memory because you invoke undefined behavior:

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

In fact, when I fix that problem and run valgrind --leak-check=full ./auto_ptr_app on the result, it tells me that no leak is possible.

like image 136
nijansen Avatar answered Jan 22 '23 07:01

nijansen


I've just run two valgrind tests on the following pieces of code:

First run:

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;
} 

Second run:

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;
}

While Valgrind indeed shows possible memory leaks in both cases, the warnings it displays are exactly the same (same number of warnings, same text of warnings, same stack) for both of them, pointing somewhere outside of my code to linux .so files. Thus, we can assume that the way you use the array of auto_ptr is fine. However, as it is stated in comments, since C++0x (which is the current C++ standard), auto_ptr is considered deprecated because of it's weird copy behaviour (you can find more info, for example, in this article). It is advised to use std::unique_ptr instead.

Now, if you are having some extra memory leaks in your code, then most likely it happens because of your own classes. Unfortunately, you haven't included them into the question, so we can't tell. In such a case, you should check your classes' constructors and destructors for memory leaks, or at least show us your classes. Another cause may be the typo in the array index that you have in the code (pbase[3], which is out of bonds).

like image 43
SingerOfTheFall Avatar answered Jan 22 '23 08:01

SingerOfTheFall