You are here:

C++/what could be wrong with my code?

Advertisement


Question
Hello,

i am not sure but could it be that i already deleted the memory to store the object cuz i cant figure out the error in this code:



#include<iostream>
#include<cstdlib>
using namespace std;

class dyna{
     int *p;
     public:
         dyna(int i);
         ~dyna(){free(p); cout<<"freeing\n";}
         int get(){return *p;}
         };
     dyna::dyna(int i){
         p = (int*)malloc(sizeof(int));
         if(!p){
         cout<<"allocation failure\n";
         exit(1);
         }
         *p = i;
         }
     
     //return a negative value of *ob.p
     int neg(dyna ob)
         {
         return -ob.get();
         }
     
     
     int main(){
         
         dyna o(-10);
         cout<<o.get()<<"\n";
         cout<<neg(o)<<"\n";
         
         dyna o2(20);
         cout<<o2.get()<<"\n";
         cout<<neg(o2)<<"\n";
         
         dyna o(-10);
         cout<<o.get()<<"\n";
         cout<<neg(o)<<"\n";
         
         return 0;
         }   
         
   ps: please, abit concise explanation will do cuz i have been on this all day.. thanks


Answer
Hello Henry.

Yes, you are freeing memory when you don't want to. When you call

int neg(dyna ob)
{
   return -ob.get();
}

a copy is made of the dyna object passed in. Since there is no copy constructor, the compiler provides a default copy constructor but the default only does a shallow copy. What you end up with is a dyna object in main and a dyna object in neg, and they both point to the same allocated memory. When neg exits, the copy is destroyed, the destructor deletes the allocated memory and the dyna object in main is left pointing to freed memory.

As a general rule, if you object allocates a resource, such as memory, it should also have a copy constructor which will make a deep copy, or a private copy constructor with no implementation. A private copy constructor will disable copying and prevent this situation. Sometimes copying makes no sense, such as when the memory is large or the resource is a file.

You can also pass the dyna object to neg by reference. Passing by reference will not cause a copy. Passing by reference is the only way the compiler will allow if the copy constructor is private. In fact, passing by reference is the correct way, unless there is a reason to make a copy.

For a private copy constructor add this to the dyna class
private:
   dyna(const dyna& ob); // unimplemented private copy constructor.

For a real copy constructor add the above, but make it public, then add this implementation
dyna::dyna(const dyna& ob)
{
  p = (int*)malloc(sizeof(int));
  if(!p){
       cout<<"allocation failure\n";
       exit(1);
  }
  *p = *ob.p;
}


To pass by reference to neg, write the function like this:

int neg(dyna& ob)
or even better
int neg(const dyna& ob)

It is the '&' character which causes passing by reference.

Also, your last dyna object in main is named 'o' and there is already an 'o' in main. That is causing a compiler problem.


Best regards
Zlatko

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2016 About.com. All rights reserved.