Thread: New/delete - problem with memory.

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    76

    New/delete - problem with memory.

    Hi,
    I have such code:
    Code:
    #include <cstdio>
    
    class n
    {
    public:
            int     *num;
            n do_something(n& a, n& b)
            {
                    n       lala=a;
                    return  lala;
            }
            n(int i =1)
            {
                    num=new int[i];
            }
            ~n()
            {
                    delete[] num;
            }
    };
    
    int main()
    {
            n       a(5),
                    b(3);
            n       c=a.do_something(a,b);
            return 0;
    }
    maybe it makes no sense but I have a similar situation in my program so I just simplified it a little bit.
    and I receive a warning:
    a.out in free(): warning: chunk is already free
    And I can't see any situation where the hell some pieace of memory is freed twice. Can anyone explain me that ?
    Regards.
    apacz.

  2. #2
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    The problem is here:
    Code:
    n       lala=a;
    You're using the default copy constructor to initialize lala, which copies the pointer but not the dynamic memory. So you have two objects which alias the same block of memory, and when the destructor is called for both, you're freeing the memory twice.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    And the solution of course is to always create a custom copy constructor when dealing with a class that uses pointers/dynamic memory. You cannot rely on the default copy constructor to work in these cases for this very reason.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  4. #4
    Registered User
    Join Date
    May 2005
    Posts
    76
    Thank you for replies. I got it now. I have modified my code a little bit:
    Code:
    #include <cstdio>
    
    class n
    {
    public:
            int     *num,
                    size;
            n& operator=(const n& a)
            {
                    printf("hm\n");
                    size=a.size;
                    num=new int[size];
                    for(int i = 0; i < size; i++)
                            num[i]=a.num[i];
                    return  *this;
            }
            n do_something(n& a, n& b)
            {
                    n       lala=a;
                    return  lala;
            }
            n(int i =1)
            {
                    size=i;
                    num=new int[i];
                    for(int k = 0; k < size; k++)
                            num[k]=0;
            }
            ~n()
            {
                    delete[] num;
            }
    };
    
    int main()
    {
            n       a(5),
                    b(3);
            n       c=a.do_something(a,b);
            return 0;
    }
    As the way as it should be corrected I hope. But I don't now if I have overloaded the operator = properly ? Becouse it seems not to be called.
    Regards.

  5. #5
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    It's not called because you're using the copy constructor, not the copy assignment operator. This should work better, though it's a good idea to have both a copy constructor and a copy assignment operator if you have one. It's also possible to define the copy constructor in terms of the copy assignment operator, but I'll leave that to you.
    Code:
    #include <cstdio>
    
    class n
    {
    public:
      int     *num,
        size;
      n do_something(n& a, n& b)
      {
        n       lala=a;
        return  lala;
      }
      n(int i =1)
      {
        size=i;
        num=new int[i];
        for(int k = 0; k < size; k++)
          num[k]=0;
      }
      n(const n& a)
      {
        // Protect against self assignment
        if (this == &a) return;
        printf("hm\n");
        size=a.size;
        num=new int[size];
        for(int i = 0; i < size; i++)
          num[i]=a.num[i];
      }
      ~n()
      {
        delete[] num;
      }
    };
    
    int main()
    {
      n       a(5),
        b(3);
      n       c=a.do_something(a,b);
      return 0;
    }

  6. #6
    Registered User
    Join Date
    May 2005
    Posts
    76
    Ok, I understand. Thanks.
    Regards,
    apacz

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    hmm... there's no need to check for self-assignment in the copy constructor, is there? After all, the object being constructed cannot possibly be the object copied.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    >After all, the object being constructed cannot possibly be the object copied.
    If you're too lazy to write both and self assignment is an important issue for one that's not related to the problem, what would you do?

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Since you can implement copy construction in terms of copy assignment (default construct and assign), but not the other way round, it doesn't make sense to put the self-assignment test in the copy constructor, since only copy assignment needs it.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The copy assignment operator must check for self assignment, and it should also delete the existing pointer. The copy constructor doesn't have to do either.

    Also, in all constructors you should make sure num is set to 0 if you don't call new. This isn't a problem with the current code, but it could become a problem if you forget to add it to additional constructors.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with linked list and shared memory
    By Sirfabius in forum C Programming
    Replies: 10
    Last Post: 11-10-2008, 04:45 PM
  2. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  3. Assignment Operator, Memory and Scope
    By SevenThunders in forum C++ Programming
    Replies: 47
    Last Post: 03-31-2008, 06:22 AM
  4. Mysterious memory allocation problem
    By TomServo1 in forum C Programming
    Replies: 7
    Last Post: 07-08-2007, 11:29 AM
  5. Memory Problem - I think...
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 10-24-2001, 12:14 PM