Query on new operator for object construction

  • Thread starter bharath.donnipad
  • Start date
B

bharath.donnipad

Hi All,

I was going through a c++ manual in msdn site
"http://msdn2.microsoft.com/en-us/library/kewsb8ba.aspx". There there
was a small note on usage of new operator :
"When new is used to allocate memory for a C++ class object, the
object's constructor is called after the memory is allocated."

So, I got a doubt and quickly executed below program. Its o/p is : base

#include <iostream.h>
#include <stdlib.h>
class base
{
int *p;
public:
base()
{
p=new int[1000];
std::cout<<"base";
}
};
int main()
{
base *bptr=new base;
delete bptr;
system("PAUSE");
return 0;
}

My doubt here is on "base *bptr=new base;" statement.
1. if iam right, to create an object here compiler uses ctr "base()".
So, ctr gets executed once. Since I used new here as per msdn manual
statement constructor should be called again & "base" should be printed
again.... I'm confused in this recursion..

2. I heard it's not wise to dynamically allocate memory in ctr. Why?

Can anyone please explain how this logic gets executed simply by
compiler?

Thanks in advance.

- Bharath
 
B

Bo Persson

Hi All,

I was going through a c++ manual in msdn site
"http://msdn2.microsoft.com/en-us/library/kewsb8ba.aspx". There
there
was a small note on usage of new operator :
"When new is used to allocate memory for a C++ class object, the
object's constructor is called after the memory is allocated."

So, I got a doubt and quickly executed below program. Its o/p is :
base

#include <iostream.h>
#include <stdlib.h>
class base
{
int *p;
public:
base()
{
p=new int[1000];
std::cout<<"base";
}
};
int main()
{
base *bptr=new base;
delete bptr;
system("PAUSE");
return 0;
}

My doubt here is on "base *bptr=new base;" statement.
1. if iam right, to create an object here compiler uses ctr
"base()".
So, ctr gets executed once. Since I used new here as per msdn manual
statement constructor should be called again & "base" should be
printed again....

No, why?
I'm confused in this recursion..

Obviously.

Your new in the constructor isn't allocating memory for the base
objects, but for the 1000 ints. Therefore, the base constructor is
only called once.
2. I heard it's not wise to dynamically allocate memory in ctr. Why?

If something else in the constructor would throw an exception, you
would leak the allocated memory.

In your case, it will leak anyway, as you don't have a destructor with
a delete[] p. That's another danger. :)
Can anyone please explain how this logic gets executed simply by
compiler?

It is just compiler magic. The language doesn't say how it is to be
done.


Bo Persson
 
S

Salt_Peter

Hi All,

I was going through a c++ manual in msdn site
"http://msdn2.microsoft.com/en-us/library/kewsb8ba.aspx". There there
was a small note on usage of new operator :
"When new is used to allocate memory for a C++ class object, the
object's constructor is called after the memory is allocated."

So, I got a doubt and quickly executed below program. Its o/p is : base
My doubt here is on "base *bptr=new base;" statement.
1. if iam right, to create an object here compiler uses ctr "base()".
So, ctr gets executed once. Since I used new here as per msdn manual
statement constructor should be called again & "base" should be printed
again.... I'm confused in this recursion..

First off, the statement base* ptr is a pointer, not an object.
Pointers do nothing else except hold a valid or invalid address of some
predefined type. Declaring a pointer invokes no object constructors.

In the code above, the new keyword invokes a single default base ctor.
The text at msdn is in fact wrong, because its typical for a ctor to
use an init list. Now consider what happens when a new allocation DOES
throw an exception, change the new allocation below to some
rediculously huge value.

// proj_exception
#include <iostream>
#include <stdexcept>

class base
{
int* p;
public:
base() : p( new int[1000] )
{
std::cout << "base()\n";
}
~base()
{
delete [] p;
std::cout << "~base()\n";
}
};

int main()
{
try
{
base* ptr = new base;
delete ptr;
}
catch ( const std::exception& r_e )
{
std::cout << "Error: " << r_e.what();
std::cout << std::endl;
}
return 0;
}
2. I heard it's not wise to dynamically allocate memory in ctr. Why?

Says who? When a programmer uses new, he is basicly telling the
compiler that "i'm taking over the reponsability of allocation and
deallocation". Don't expect MS to understand that statement.
If the integer allocation fails, an exception will be thrown and the
base constructor will never complete execution. So nothing needs to be
destoyed but that exception should be handled by something somewhere.

The point here is that C++ prefers that the responsability of
allocation and deallocation be well defined. Distributing allocation
overthere and distributing deallocation over here is not a good idea.
Whats needed is a way to handle allocations a smarter way: thats where
smart pointers are handy.
http://www.parashift.com/c++-faq-lite/exceptions.html

Don't loose sight of the big picture. It would be so much more usefull
to create that base class like so:

// proj_exception
#include <iostream>
#include <vector>
#include <stdexcept>

class base
{
std::vector< int > vn;
public:
base() : vn()
{
std::cout << "base()\n";
}
base(int n) : vn(n, 0)
{
std::cout << "base(int n) ";
std::cout << "vn's size = " << vn.size();
std::cout << "\n";
}
~base()
{
std::cout << "~base()\n";
}
};

// look ma! no pointers...
int main()
{
try
{
base a;
base b(1000);
}
catch ( const std::exception& r_e )
{
std::cout << "Error: " << r_e.what();
std::cout << std::endl;
}
return 0;
}

/*
base(int n) vn's size = 1000
~base()
*/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,284
Latest member
NicholeDum

Latest Threads

Top