4

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 : '['

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user1808932
  • 427
  • 1
  • 5
  • 14
  • 4
    Please post the error message, too. – arne Aug 22 '13 at 07:15
  • 6
    do you have virtual destructors? Additionally, please use unique_ptr & shared_ptr instead of the auto_ptr. Think about using a std::vector to store your pointers. – Tobias Langner Aug 22 '13 at 07:19
  • 8
    `auto_ptr` is deprecated because of its weird copying behavior. Consider switching to `std::unique_ptr` – nikolas Aug 22 '13 at 07:19
  • Not quite the same question, so not voting to close as duplicate, but [this has useful answers](http://stackoverflow.com/q/111478/1171191). – BoBTFish Aug 22 '13 at 07:22
  • 3
    One more thing; I guess it's just a typo, but you are accessing `pbase[3]` which invokes undefined behavior – nikolas Aug 22 '13 at 07:23
  • Please try to provide an [SCCE](http://sscce.org) so we have a complete overview of the problem. ["Finding the smallest possible program that shows the problem is enough to eliminate huge numbers of possible explanations."](https://twitter.com/jcoglan/statuses/370275775129206784) – Arne Mertz Aug 22 '13 at 07:26
  • Have you tried to search for "array of auto_ptr"? – Onur Aug 22 '13 at 07:32
  • Spill the beans, what is " some compile time error"? – doctorlove Aug 22 '13 at 07:41
  • i have fixed the memory leak issue, it's some stupidity from my side, while i have updated the compile time error in the question. – user1808932 Aug 22 '13 at 08:58

3 Answers3

7

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.

nikolas
  • 8,707
  • 9
  • 50
  • 70
  • A typical example of undefined behavior then, if you invoke undefined behavior you *may* have a memory leak... or pretty much anything else ! – Matthieu M. Aug 22 '13 at 08:10
  • @MatthieuM. Exactly. This is the reason why I chose the wording *it is possible* - anything is. – nikolas Aug 22 '13 at 08:10
  • @user1808932 So the index out of bounds was not causing your problem? Besides that I could only think of strange problems with polymorphism or something completely different, both which is not evident from your example – nikolas Aug 22 '13 at 08:36
  • i have fixed the leak issue, it's my stupidity, while i have updated the compile time error one. – user1808932 Aug 22 '13 at 08:59
1

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).

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
1

Your problem is probably not with auto_ptr, although that is deprecated and you should use unique_ptr or shared_ptr instead (if your compiler doesn't support C++11, use boost::shared_ptr). It seems like the leak is within your class implementation. Check if base has virtual destructor, because you need that if you want to use the class polymorphically. Also check for any members of base and derived classes and delete everything you allocated.

petersohn
  • 11,292
  • 13
  • 61
  • 98