Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does destructor get called in the following code?

Tags:

c++

Consider the following code. This code is taken from the book Object Oriented Programming With C++!-Chapter 12.Templates.

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
class vc
{
    int size2;
    int *v;
public :

    vc(int size1);
    vc(int *a);
    ~vc()
    {
        printf("\n calling destructor");
    }
    int operator *(vc );
};
vc::vc(int size1)
{
    v = new int[size2=size1];
    for(int i=0;i<this->size2;i++)
        v[i]=0;
}
vc::vc(int a[])
{

    for(int i=0;i<this->size2;i++)
    {
        v[i]=a[i];

    }
}
int vc::operator *(vc v1)
{
    int total=0;
    for(int i=0;i<size2;i++)
        total+=(v[i]*v1.v[i]);
    return total;
}

int main()
{
    int a[3]={1,2,3};
    int b[3]= {5,6,7};
    vc v1(3),v2(3);
     v1=a;
     v2=b;
    int total = v1*v2;
    cout << total;
    return 0;
}

First of all this code is not working properly. It should show 38 as output. When I started debugging this code, I found 3 is assigned to size2 after this line vc v1(3),v2(3);. But while executing the next line, control is passed to the second constructor and size2 shows a garbage value. Moreover,destructor is called after line v1=a and same happens after the next line.

Final output:

calling destructor
calling destructor
calling destructor0

Why does destructor get called 3 times? Is this code wrong?

like image 236
Heisenberg Avatar asked Feb 07 '26 04:02

Heisenberg


1 Answers

When you call v1*v2, you pass v2 to the method

int vc::operator *(vc v1)

which creates a local copy of v2. Therefore, you have an additional vc instance.

The answer for your first doubt,

But while executing the next line, control is passed to the second constructor and size2 shows a garbage value and it is not executed for three times.

is because

v1 = a;

creates a temporary vc by calling vc::vc(int a[]) and assign it to v1. However, this constructor did not initialize size2. So you get a garbage value.

A cleaner approach would be to pass an array as well as its size:

vc::vc(int a[], int size1) {                                                                                       
    v = new int[size2=size1];                                                                                      
    for(int i=0; i<size2; i++)                                                                                     
        v[i] = a[i];                                                                                                 
}

int main()
{
    int a[3]={1,2,3};
    int b[3]= {5,6,7};
    vc v1(a, 3), v2(b, 3); 
    int total = v1*v2;
    cout << total;
    return 0;
}

Then total will be 38.

like image 162
Yang Avatar answered Feb 12 '26 15:02

Yang



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!