473,387 Members | 1,536 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

different behavior of destructor

Following code is behaving strange:
class WithPointerMember
{
char* str;
const size_t size;
public:
WithPointerMember():size(15) //ctor
{
str = new char[size];
strcpy(str, "Initialized");
}

WithPointerMember (const WithPointerMember& other):size(other.size)
//copy ctor
{
str = new char[size];
for(size_t i=0;i<size;i++)
str[i]= other.str[i];
}

char* GetString(void) const
{
return str;
}

~WithPointerMember() //dtor
{
delete [] str;
}
};

Now In main function first I do like
int main(void)
{
WithPointerMember wpm;
WithPointerMember wpm1 = wpm; <---------- Initializing wpm1 from wpm
cout<<"string="<<wpm.GetString()<<"\n";
wpm.~WithPointerMember();
cout<<"string="<<wpm.GetString()<<endl;
cout<<"string="<<wpm1.GetString()<<endl;
return 0;
}

The output is expected :

string=Initialized
string=
string=Initialized

Now I change my main:
int main(void)
{
WithPointerMember wpm;
cout<<"string="<<wpm.GetString()<<"\n";
wpm.~WithPointerMember();
WithPointerMember *wpm1 = new WithPointerMember(); <-------
Initializing wpm1 from new
cout<<"string="<<wpm.GetString()<<endl;
cout<<"string="<<wpm1->GetString()<<endl;
return 0;
}

Here Output is : ( which is not expected )
string=Initialized
string=Initialized <------ This is not expected
string=Initialized

Can anybody explain that what is going wrong here. I am running code on
Windows using MSVC compiler

Thanks.
sacgarg

Mar 23 '06 #1
6 1578
>
Now I change my main:
int main(void)
{
WithPointerMember wpm;
cout<<"string="<<wpm.GetString()<<"\n";
wpm.~WithPointerMember();
WithPointerMember *wpm1 = new WithPointerMember(); <-------
Initializing wpm1 from new
cout<<"string="<<wpm.GetString()<<endl;
cout<<"string="<<wpm1->GetString()<<endl;
return 0;
}

Here Output is : ( which is not expected )
string=Initialized
string=Initialized <------ This is not expected


It's expected, actually. You called the destructor before, which
deletes WithPointerMember::str. Anything you do afterwards that involve
the str member can produce anything. Do you really need to call the
destructor explicitly? And have you considered using std::string?

Mar 23 '06 #2
sacgarg wrote:
Following code is behaving strange:
class WithPointerMember
{
char* str;
const size_t size;
public:
WithPointerMember():size(15) //ctor
{
str = new char[size];
strcpy(str, "Initialized");
}

WithPointerMember (const WithPointerMember& other):size(other.size)
//copy ctor
{
str = new char[size];
for(size_t i=0;i<size;i++)
str[i]= other.str[i];
}

char* GetString(void) const
{
return str;
}

~WithPointerMember() //dtor
{
delete [] str;
}
};

Now In main function first I do like
int main(void)
{
WithPointerMember wpm;
WithPointerMember wpm1 = wpm; <---------- Initializing wpm1 from wpm
Beware, you have not created an operator=, although you are not using it
here. Prefer:

WithPointerMember wpm1(wpm);
cout<<"string="<<wpm.GetString()<<"\n";
expect:
string=Initialized
wpm.~WithPointerMember();
OK, this deallocated the internal string.
cout<<"string="<<wpm.GetString()<<endl;
Undefined behaviour. You cannot call member functions on destructed
objects. The rest of the program is useless.
cout<<"string="<<wpm1.GetString()<<endl;
return 0;
What do you expect to happen now? wgm and wgm1 will be destructed, you
cannot call the destructor of an object twice, it invokes undefined
behaviour.
}

The output is expected :

string=Initialized
Up to here is fine.
string=
string=Initialized
You cannot reasonably expect anything after invoking undefined behaviour.
Now I change my main:
int main(void)
{
WithPointerMember wpm;
cout<<"string="<<wpm.GetString()<<"\n";
Expect:
string=Initialized
wpm.~WithPointerMember();
WithPointerMember *wpm1 = new WithPointerMember(); <-------
Initializing wpm1 from new
cout<<"string="<<wpm.GetString()<<endl;
wpm has been destructed, more undefined behaviour...
cout<<"string="<<wpm1->GetString()<<endl;
return 0;
}

Here Output is : ( which is not expected )
string=Initialized
string=Initialized <------ This is not expected
string=Initialized

Can anybody explain that what is going wrong here. I am running code on
Windows using MSVC compiler


Stop calling the destructor explicitly. Trust me, you'll never need to.
What are you trying to achieve?

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 23 '06 #3

fe****************@gmail.com wrote:

Now I change my main:
int main(void)
{
WithPointerMember wpm;
cout<<"string="<<wpm.GetString()<<"\n";
wpm.~WithPointerMember();
WithPointerMember *wpm1 = new WithPointerMember(); <-------
Initializing wpm1 from new
cout<<"string="<<wpm.GetString()<<endl;
cout<<"string="<<wpm1->GetString()<<endl;
return 0;
}

Here Output is : ( which is not expected )
string=Initialized
string=Initialized <------ This is not expected


It's expected, actually. You called the destructor before, which
deletes WithPointerMember::str. Anything you do afterwards that involve
the str member can produce anything. Do you really need to call the
destructor explicitly? And have you considered using std::string?


calling destructor explicitly is intentional, just to test the
behaviour.

I have already read in 'Undefined behaviour in C' that once you free
the memory, referencing it again can give you anything.

Is it same here?

Mar 23 '06 #4

Ben Pope wrote:
sacgarg wrote:
Following code is behaving strange:
class WithPointerMember
{
char* str;
const size_t size;
public:
WithPointerMember():size(15) //ctor
{
str = new char[size];
strcpy(str, "Initialized");
}

WithPointerMember (const WithPointerMember& other):size(other.size)
//copy ctor
{
str = new char[size];
for(size_t i=0;i<size;i++)
str[i]= other.str[i];
}

char* GetString(void) const
{
return str;
}

~WithPointerMember() //dtor
{
delete [] str;
}
};

Now In main function first I do like
int main(void)
{
WithPointerMember wpm;
WithPointerMember wpm1 = wpm; <---------- Initializing wpm1 from wpm
Beware, you have not created an operator=, although you are not using it
here. Prefer:

Thanks for mentioning that, but I was aware that I am not going to use
it.
WithPointerMember wpm1(wpm);
cout<<"string="<<wpm.GetString()<<"\n";
expect:
string=Initialized
wpm.~WithPointerMember();


OK, this deallocated the internal string.
cout<<"string="<<wpm.GetString()<<endl;


Undefined behaviour. You cannot call member functions on destructed
objects. The rest of the program is useless.

Here by calling destructor explicitely, I am not destructing object
itself, instead I am deleting the internal string, then how come object
is destructed? I am confused.
cout<<"string="<<wpm1.GetString()<<endl;
return 0;


What do you expect to happen now? wgm and wgm1 will be destructed, you
cannot call the destructor of an object twice, it invokes undefined
behaviour.
}

The output is expected :

string=Initialized


Up to here is fine.
string=
string=Initialized


You cannot reasonably expect anything after invoking undefined behaviour.
Now I change my main:
int main(void)
{
WithPointerMember wpm;
cout<<"string="<<wpm.GetString()<<"\n";


Expect:
string=Initialized
wpm.~WithPointerMember();
WithPointerMember *wpm1 = new WithPointerMember(); <-------
Initializing wpm1 from new
cout<<"string="<<wpm.GetString()<<endl;


wpm has been destructed, more undefined behaviour...
cout<<"string="<<wpm1->GetString()<<endl;
return 0;
}

Here Output is : ( which is not expected )
string=Initialized
string=Initialized <------ This is not expected
string=Initialized

Can anybody explain that what is going wrong here. I am running code on
Windows using MSVC compiler


Stop calling the destructor explicitly. Trust me, you'll never need to.
What are you trying to achieve?

This is intentional for testing the behaviour of pointer member.
Ben Pope
--
I'm not just a number. To many, I'm known as a string...


Mar 23 '06 #5
sacgarg wrote:
Ben Pope wrote:
Beware, you have not created an operator=, although you are not using it
here. Prefer:

Thanks for mentioning that, but I was aware that I am not going to use
it.


In real code, you should declare it private and not implement it.
Attempts to use it will be caught by the compiler.
Undefined behaviour. You cannot call member functions on destructed
objects. The rest of the program is useless.

Here by calling destructor explicitely, I am not destructing object
itself, instead I am deleting the internal string, then how come object
is destructed? I am confused.


You are destructing the object, the compiler may be doing some other
background stuff that you are not aware of. It is as free to do this,
as it is to implement it's own constructor, destructor, copy constructor
and assignment operator if you do not provide one.

In that destructor you deallocate the internal buffer. One of the
invariants of your object is that the internal buffer exists. Take a
look at the member functions, they all assume that str points to a valid
char[] (GetString may be able to get away with a NULL str). Therefore,
having str point to a valid char[], or NULL is an invariant.
Stop calling the destructor explicitly. Trust me, you'll never need to.
What are you trying to achieve?

This is intentional for testing the behaviour of pointer member.


Well, after invoking undefined behaviour, your tests are meaningless.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 23 '06 #6
sacgarg wrote:
WithPointerMember wpm1(wpm);
> cout<<"string="<<wpm.GetString()<<"\n";
expect:
string=Initialized
> wpm.~WithPointerMember();


OK, this deallocated the internal string.
> cout<<"string="<<wpm.GetString()<<endl;


Undefined behaviour. You cannot call member functions on destructed
objects. The rest of the program is useless.

Here by calling destructor explicitely, I am not destructing object
itself,


Yes you are. Guess why it is called "destructor".
instead I am deleting the internal string, then how come object is
destructed? I am confused.


When an object is created, two things happen:

- raw memory is acquired
- a constructor is used to turn that raw memory into an object

After the destructor was executed, you can't expect an object anymore. It is
now back to raw memory.
Mar 23 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Dave | last post by:
What is the expected output of this program and why??? #include <iostream> using namespace std; class base {
10
by: aka | last post by:
// classA.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; static unsigned int count = 0;
4
by: Abhishek Srivastava | last post by:
Hello All, I wrote a program in which I have a OleDbConnection which I open in the contructor and close in the Destructor. When I run the program I get the following error Unhandled...
9
by: Jeff Louie | last post by:
In C# (and C++/cli) the destructor will be called even if an exception is thrown in the constructor. IMHO, this is unexpected behavior that can lead to an invalid system state. So beware! ...
15
by: Dilip | last post by:
I am aware that the C++ standard in its present form does not say anything about threads, however I do have a relevant question. I am working on Windows XP/VC++ 8.0. Is there a problem new'ing...
3
by: Zongjun Qi | last post by:
Hey, In the book <Effective C++>, the author provides an example to prove why we need "pass by reference". I redoed the example, and found something interesting. The codes are:...
10
by: Chris Thomasson | last post by:
I am working on a high-speed futures implementation in C++, and was tinkering around with ways to wrap the function pointer logic. I am a C/Assembly programmer that doesn't make a lot of use of...
15
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and...
2
by: dolphin | last post by:
What is the different between c++ call convention and c call convention?Can some give some examples?
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.