Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Question on auto_ptr, Which function will call first?

Reply
Thread Tools

Question on auto_ptr, Which function will call first?

 
 
asm23
Guest
Posts: n/a
 
      10-03-2008
Hi, everyone, I'm studying the <<Thinking in C++>> volume Two. In
Chapter One, the example code : Auto_ptr.cpp
//-------------------------------------------------------
#include <memory>
#include <iostream>
#include <cstddef>
using namespace std;

class TraceHeap {
int i;
public:
static void* operator new(size_t siz) { //*****NOTE A
void* p = :perator new(siz);
cout << "Allocating TraceHeap object on the heap "
<< "at address " << p << endl;
return p;
}
static void operator delete(void* p) {
cout << "Deleting TraceHeap object at address "
<< p << endl;
:perator delete(p);
}
TraceHeap(int i) //*******NOTE B
: i(i)
{
;
}
int getVal() const { return i; }
};



int main() {
auto_ptr<TraceHeap> pMyObject(new TraceHeap(5));
cout << pMyObject->getVal() << endl; // Prints 5
}
//------------------------------------------------------------------

My question is :

In My code: which code will be called first? The *NOTE A* or *NOTE B* ?
And Why?

I'm debugging through this code and found that *NOTE A* will called
first. Can someone explained it?
When I trace into the *new* function, the *siz* value is 4. I don't know
why it will be 4?

Thank you for reading my message.


 
Reply With Quote
 
 
 
 
Jiøí Paleèek
Guest
Posts: n/a
 
      10-03-2008
On Fri, 03 Oct 2008 18:00:28 +0200, asm23 <> wrote:

> Hi, everyone, I'm studying the <<Thinking in C++>> volume Two. In
> Chapter One, the example code : Auto_ptr.cpp
> //-------------------------------------------------------
> #include <memory>
> #include <iostream>
> #include <cstddef>
> using namespace std;
>
> class TraceHeap {
> int i;
> public:
> static void* operator new(size_t siz) { //*****NOTE A
> void* p = :perator new(siz);
> cout << "Allocating TraceHeap object on the heap "
> << "at address " << p << endl;
> return p;
> }
> static void operator delete(void* p) {
> cout << "Deleting TraceHeap object at address "
> << p << endl;
> :perator delete(p);
> }
> TraceHeap(int i) //*******NOTE B
> : i(i)
> {
> ;
> }
> int getVal() const { return i; }
> };
>
>
>
> int main() {
> auto_ptr<TraceHeap> pMyObject(new TraceHeap(5));
> cout << pMyObject->getVal() << endl; // Prints 5
> }
> //------------------------------------------------------------------
>
> My question is :
>
> In My code: which code will be called first? The *NOTE A* or *NOTE B* ?
> And Why?
>
> I'm debugging through this code and found that *NOTE A* will called
> first. Can someone explained it?


I haven't looked up the standard, but common sense tells the constructor
cannot be called before memory allocation, as it needs to construct an
object in the memory allocated by the new operator.

> When I trace into the *new* function, the *siz* value is 4. I don't know
> why it will be 4?


That's sizeof(TraceHeap)

Regards
Jiri Palecek
 
Reply With Quote
 
 
 
 
asm23
Guest
Posts: n/a
 
      10-04-2008
Victor Bazarov wrote:
>
> The 'operator new' function is the class-wide allocation function.
> Before any object of that class can be constructed in free store, the
> memory has to be allocated. That's why the allocation happens before
> the construction.
>


Thanks Victor. I understand, I confused with *allocation* and
*construction*. But now, I know they are different and executing
sequence of them.

>
> I think I just did.
>
>
> The object of type TraceHeap that you're creating has a single data
> member, 'int i', and no virtual functions or base classes. It's
> reasonable to conclude that nothing contributes to the size of the
> object except the data members. On your platform 'int' probably has the
> size of 4 bytes... Try printing out 'sizeof(TraceHeap)' somewhere, what
> do you get.
>
> V


oh, Yes, the sizeof(TraceHeap) is 4. But I still have a puzzle. Why
these is a *static* before the overloaded new and delete operation?
I do know static function doesn't pass the *this* parameters. But in
this case, a static new or a normal new seems have no difference.

Thank you for help me.

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      10-04-2008
On Oct 3, 6:00 pm, asm23 <asmwarr...@gmail.com> wrote:
> Hi, everyone, I'm studying the <<Thinking in C++>> volume Two.
> In Chapter One, the example code : Auto_ptr.cpp
> //-------------------------------------------------------
> #include <memory>
> #include <iostream>
> #include <cstddef>
> using namespace std;


> class TraceHeap {
> int i;
> public:
> static void* operator new(size_t siz) { //*****NOTE A
> void* p = :perator new(siz);
> cout << "Allocating TraceHeap object on the heap "
> << "at address " << p << endl;
> return p;
> }
> static void operator delete(void* p) {
> cout << "Deleting TraceHeap object at address "
> << p << endl;
> :perator delete(p);
> }
> TraceHeap(int i) //*******NOTE B
> : i(i)
> {
> ;
> }
> int getVal() const { return i; }
> };


> int main() {
> auto_ptr<TraceHeap> pMyObject(new TraceHeap(5));
> cout << pMyObject->getVal() << endl; // Prints 5
> }
> //------------------------------------------------------------------


> My question is :


> In My code: which code will be called first? The *NOTE A* or
> *NOTE B* ? And Why?


NOTE A, obviously. The trivial reason is because that is what
the language requires. Of course, the reason the language
requires this is that it couldn't possibly work otherwise: you
have to allocate the memory for the object before you can
construct it.

> I'm debugging through this code and found that *NOTE A* will called
> first. Can someone explained it?


Think. What would it mean if NOTE B were called before NOTE A.

> When I trace into the *new* function, the *siz* value is 4. I don't know
> why it will be 4?


Because that's the size of a TraceHeap object on your machine.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      10-04-2008
On Oct 3, 6:17 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> The 'operator new' function is the class-wide allocation
> function. Before any object of that class can be constructed
> in free store, the memory has to be allocated. That's why the
> allocation happens before the construction.


Just a nit, but that last sentence applies to all objects, not
just those dynamically allocated. One of the particularities of
C++ is that there is NO syntax for calling a constructor without
formally allocating memory. (In the case of placement new, of
course, the "allocation" is purely formal. But you still have
to tell the compiler what memory it should use.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      10-04-2008
asm23 wrote:
>
> oh, Yes, the sizeof(TraceHeap) is 4. But I still have a puzzle. Why
> these is a *static* before the overloaded new and delete operation?
> I do know static function doesn't pass the *this* parameters. But in
> this case, a static new or a normal new seems have no difference.
>
> Thank you for help me.


You are right, it doesn't matter. The operators new and delete are
static, whether you write 'static' or not.

The author of this code perhaps believed that it is more clear if this
is stated explicitly. Maybe it is not?


Bo Persson


 
Reply With Quote
 
asm23
Guest
Posts: n/a
 
      10-04-2008
Bo Persson wrote:
> asm23 wrote:
>> oh, Yes, the sizeof(TraceHeap) is 4. But I still have a puzzle. Why
>> these is a *static* before the overloaded new and delete operation?
>> I do know static function doesn't pass the *this* parameters. But in
>> this case, a static new or a normal new seems have no difference.
>>
>> Thank you for help me.

>
> You are right, it doesn't matter. The operators new and delete are
> static, whether you write 'static' or not.
>
> The author of this code perhaps believed that it is more clear if this
> is stated explicitly. Maybe it is not?
>
>
> Bo Persson
>
>

Thanks Bo, I see.
 
Reply With Quote
 
asm23
Guest
Posts: n/a
 
      10-04-2008
James Kanze wrote:
> NOTE A, obviously. The trivial reason is because that is what
> the language requires. Of course, the reason the language
> requires this is that it couldn't possibly work otherwise: you
> have to allocate the memory for the object before you can
> construct it.
>
>> I'm debugging through this code and found that *NOTE A* will called
>> first. Can someone explained it?

>
> Think. What would it mean if NOTE B were called before NOTE A.
>
>> When I trace into the *new* function, the *siz* value is 4. I don't know
>> why it will be 4?

>
> Because that's the size of a TraceHeap object on your machine.
>
> --
> James Kanze (GABI Software) email:
> Conseils en informatique orientée objet/
> Beratung in objektorientierter Datenverarbeitung
> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Thanks, James.
Now, I understand the important concept of " allocating before
construction ".

I think the author overload the operator new of TraceHeap is just to
show some message.

static void* operator new(size_t siz) { //*****NOTE A
void* p = :perator new(siz);
cout << "Allocating TraceHeap object on the heap "
<< "at address " << p << endl;
return p;
}

the parameter *size_t siz* will be filled at compiling time. So, the
compiler will set the siz value to sizeof(TraceHeap).

Is my understanding right? Thanks.
 
Reply With Quote
 
Hendrik Schober
Guest
Posts: n/a
 
      10-05-2008
James Kanze wrote:
> On Oct 3, 6:17 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> The 'operator new' function is the class-wide allocation
>> function. Before any object of that class can be constructed
>> in free store, the memory has to be allocated. That's why the
>> allocation happens before the construction.

>
> Just a nit, but that last sentence applies to all objects, not
> just those dynamically allocated. One of the particularities of
> C++ is that there is NO syntax for calling a constructor without
> formally allocating memory. [...]


I don't doubt that you're right, but I'd like to know
what this
std::string("huh?")
is if it's not the explicit invocation of a constructor.

Schobi
 
Reply With Quote
 
asm23
Guest
Posts: n/a
 
      10-06-2008
Victor Bazarov wrote:
> Hendrik Schober wrote:
>> James Kanze wrote:
>>> On Oct 3, 6:17 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>>>> The 'operator new' function is the class-wide allocation
>>>> function. Before any object of that class can be constructed
>>>> in free store, the memory has to be allocated. That's why the
>>>> allocation happens before the construction.
>>>
>>> Just a nit, but that last sentence applies to all objects, not
>>> just those dynamically allocated. One of the particularities of
>>> C++ is that there is NO syntax for calling a constructor without
>>> formally allocating memory. [...]

>>
>> I don't doubt that you're right, but I'd like to know
>> what this
>> std::string("huh?")
>> is if it's not the explicit invocation of a constructor.

>
> It is a creation of a temporary object, which of course *causes* a call
> to the constructor (and later a destructor at the end of the object's
> lifetime, which is impossible for you to prevent, BTW).
>
> You *may* call it an "explicit invocation", and start beating that dead
> horse again, but let me just make a note here: if it's an invocation,
> it's not explicit. The constructor is *invoked* or *called* by the
> execution environment when you *create an object*. The language of the
> Standard is such that there cannot be *direct* call to the constructor
> simply because constructors do not have names and cannot be found during
> lookup.
>
> No, back to the subject at hand. James said you cannot call (or invoke,
> if you will) a constructor without allocating memory first, and not that
> you can't call a constructor (or cause its invocation). When you do
>
> std::string("bleh")
>
> the system will *still* allocate memory for you first, and then invoke
> the constructor to construct the object in that memory. You do not call
> the constructor. You do not allocate memory. The syntax is for object
> creation, and you give the system the responsibility for the low-level
> stuff.
>
> V

That's a good clarification! Thanks.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to call function whose function call with arguments is in astring Options grbgooglefan C Programming 4 01-30-2008 05:12 PM
How to call function whose function call with arguments is in astring grbgooglefan C++ 2 01-30-2008 07:18 AM
How to call function whose function call with arguments is in astring Options grbgooglefan C Programming 0 01-30-2008 04:19 AM
What is the correct grammar to make a function call by using static member data which is a pointer to a ordinary class member function? zaeminkr@gmail.com C++ 3 07-06-2007 12:50 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57