Thread: Why the destructor is called?

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    2

    Why the destructor is called?

    Hello everyone!

    I'm coding an application and I don't understand why it isn't working. I've written a simple example to show you my problem:

    Code:
    #include <iostream>
    using std::cout;
    
    class test {
    friend test operator+(test&, test&);
    
    public:
    test() {}
    test(const int& s1, const int& s2);
    double& operator ()(int i, int j) {return v[i][j];}
    ~test();
    
    protected:
    double** v;
    int _s1, _s2;
    };
    
    int main() {
    test t(4, 4);
    test a(4, 4);
    test b(4, 4);
    
    for (int i = 0; i < 4; i++) {
    a(i, i) = i;
    b(i, i) = i + 2;
    }
    
    t = a + b;
    for (int i = 0; i < 4; i++){
    for (int j = 0; j < 4; j++)
    cout << t(i, j) << " ";
    cout << "\n";
    }
    
    system("pause");
    
    return 0;
    }
    
    test operator+(test& a, test& b)
    {
    test z(a._s1, a._s2);
    for(int i = 0; i < a._s1; i++){
    for (int j = 0; j < a._s2; j++)
    z(i, j) = a(i, j) + b(i, j);
    }
    
    return z;
    }
    
    test::test(const int& s1, const int& s2) {
    v = new double*[s1];
    for (int i = 0; i < s1; i++)
    v[i] = new double[s2];
    
    _s1 = s1;
    _s2 = s2;
    
    for (int i = 0; i < s1; i++){
    for (int j = 0; j < s2; j++)
    v[i][j] = 0.0;
    }
    }
    
    test::~test() {
    for (int i = 0; i < _s1; i++)
    delete [] v[i];
    delete [] v;
    }

    The problem is that when I do "t = a + b;" the "return z" in the function "test operator+(test&, test&);" it calls the destructor for z before it returns and this makes a crash because the variable t doesn't have anything.

    Also, the destructor for "t" is called right after the return from the function causing another crash.

    The interesting part is that if I adapt the code to sum vectors intead of matrices, it works!

    Any help would be appreciated.

    Thanks,

    scherzo

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, the problem is that you haven't got a copy/assignment operator for your class, so when you delete the z's v[] (which is done correctly after the "return z" has been copied to the t variable in your main). You can see the t value change to the same value as the z if you look at a memory view of the t memory.

    The correct thing to do is not to copy the v pointer, but to copy the CONTENT of v.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I added the following:
    Code:
    test::test(test &t)
    {
    	int i;
    	v = new double*[t._s1];
    	for (i = 0; i < t._s1; i++)
    		v[i] = new double[t._s2];
    	_s1 = t._s1;
    	_s2 = t._s2;
    
    	for(i = 0; i < t._s1; i++) {
    		for(int j = 0; j < t._s2; j++) 
    			v[i][j] = t.v[i][j];
    	}
    }
    
    
    test & test::operator=(const test &t)
    {
    	assert(t._s2 == _s2 && t._s1 == _s1);
    	for(int i = 0; i < t._s1; i++) {
    		for(int j = 0; j < t._s2; j++) 
    			v[i][j] = t.v[i][j];
    	}
    	return *this;
    }
    And now the program executes correctly.
    Code:
    Output:
    2 0 0 0
    0 4 0 0
    0 0 6 0
    0 0 0 8
    You probably also want to add const as marked with red:
    Code:
    test operator+(const test& a, const test& b)
    	double& operator ()(int i, int j) const {return v[i][j];}
    --
    Mats
    Last edited by matsp; 10-22-2007 at 02:00 PM. Reason: Fix missing end-tag [premature submit]
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    [quote]
    Code:
    test & test::operator=(const test &t)
    {
    	assert(t._s2 == _s2 && t._s1 == _s1);
    Which makes me wonder, wouldn't the correct behaviour - instead of asserting - be to resize the array.

    All in all, there might be much less trouble if you used a std::vector<std::vector<double> > instead of a double** (where vector is a container for dynamically allocated array).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    [QUOTE=anon;681089]
    Code:
    test & test::operator=(const test &t)
    {
    	assert(t._s2 == _s2 && t._s1 == _s1);
    Which makes me wonder, wouldn't the correct behaviour - instead of asserting - be to resize the array.

    All in all, there might be much less trouble if you used a std::vector<std::vector<double> > instead of a double** (where vector is a container for dynamically allocated array).
    Probably right there. I just put the assert in to convince myself that it wasn't complete rubbish. Since all of the code uses one size, it would only fire if the object wasn't properly initialized.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Oct 2007
    Posts
    2
    Thanks for all matsp and anon.

    Now I know what was going on.

    Best regards,

    scherzo

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Destructor being called on SGI hash_map key
    By cunnus88 in forum C++ Programming
    Replies: 4
    Last Post: 02-11-2009, 12:05 AM
  2. Replies: 4
    Last Post: 09-21-2008, 02:27 PM
  3. callback from exe called with system()
    By leonv in forum C Programming
    Replies: 3
    Last Post: 01-25-2008, 04:12 PM
  4. AAARG!!! mental block, what is this character called: ')'
    By compjinx in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-29-2002, 10:29 PM
  5. Program ive been working on called ChatMate
    By dirkduck in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 01-23-2002, 09:05 PM