469,578 Members | 1,888 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,578 developers. It's quick & easy.

excuse me if this is a real noddy question ...

but ireally does need clearing up ...

Traditionally (i.e. in C++) I might do the following:

SomeObj ptrSomeObj;
for(int i = 0; i < iCount; ++i)
{
ptrSomeObj = new SomeObj();
ptrSomeObj->MethodOne();
delete ptrSomeObj;
}

Now, as far as I'm aware, the equivalent code in C# is this:

SomeObj myObj;
for(int i = 0; i < iCount; ++i)
{
myObj = new SomeObj();
myObj.MethodOne();
}

Now the question comes ....

traditionally, I would declare my pointer OUTSIDE of the for loop (for
obvious reasons), but whilst reviewing code produced by several "seasoned"
developers, their C# code does the opposite, for example:

for(int i = 0; i < iCount; ++i)
{
SomeObj myObj = new SomeObj();
myObj.MethodOne();
}

what I want to know is, yes, we are using a managed heap, but that doesn't
necessarily make that last bit of code any more acceptable does it?

Or am I completely wrong.

--
--

Of all words of tongue and pen, the saddest are: "It might have been"
Nov 17 '05 #1
7 1159
whoops ... it's been a few months since I last used C++ so you will have to
forgive my omission of the * in my pointer decls (you see how easy it is to
forget!)
--
--

Of all words of tongue and pen, the saddest are: "It might have been"
"billr" wrote:
but ireally does need clearing up ...

Traditionally (i.e. in C++) I might do the following:

SomeObj ptrSomeObj;
for(int i = 0; i < iCount; ++i)
{
ptrSomeObj = new SomeObj();
ptrSomeObj->MethodOne();
delete ptrSomeObj;
}

Now, as far as I'm aware, the equivalent code in C# is this:

SomeObj myObj;
for(int i = 0; i < iCount; ++i)
{
myObj = new SomeObj();
myObj.MethodOne();
}

Now the question comes ....

traditionally, I would declare my pointer OUTSIDE of the for loop (for
obvious reasons), but whilst reviewing code produced by several "seasoned"
developers, their C# code does the opposite, for example:

for(int i = 0; i < iCount; ++i)
{
SomeObj myObj = new SomeObj();
myObj.MethodOne();
}

what I want to know is, yes, we are using a managed heap, but that doesn't
necessarily make that last bit of code any more acceptable does it?

Or am I completely wrong.

--
--

Of all words of tongue and pen, the saddest are: "It might have been"

Nov 17 '05 #2
Bill,

Supposing that you won't need to use the contents of the variable after the
loop ends, the only potential reason to place the declaration outside of the
loop could be performance: assigning the references to the newly created
objects to the same "static" variable is more efficient than assigning then
to variables created dynamically on the stack. But this is an optimization
detail that an intelligent compiler can easily handle.
I think the main advantage of placing the declaration inside the loop is
locality of scope: if you make the reference local to the body of the loop,
it won't be possible to use it by mistake after the closing brace. You can't
say that of you C++ version.

Regards - Octavio

"billr" <bi***@discussions.microsoft.com> escribió en el mensaje
news:EB**********************************@microsof t.com...
but ireally does need clearing up ...

Traditionally (i.e. in C++) I might do the following:

SomeObj ptrSomeObj;
for(int i = 0; i < iCount; ++i)
{
ptrSomeObj = new SomeObj();
ptrSomeObj->MethodOne();
delete ptrSomeObj;
}

Now, as far as I'm aware, the equivalent code in C# is this:

SomeObj myObj;
for(int i = 0; i < iCount; ++i)
{
myObj = new SomeObj();
myObj.MethodOne();
}

Now the question comes ....

traditionally, I would declare my pointer OUTSIDE of the for loop (for
obvious reasons), but whilst reviewing code produced by several "seasoned"
developers, their C# code does the opposite, for example:

for(int i = 0; i < iCount; ++i)
{
SomeObj myObj = new SomeObj();
myObj.MethodOne();
}

what I want to know is, yes, we are using a managed heap, but that doesn't
necessarily make that last bit of code any more acceptable does it?

Or am I completely wrong.

--
--

Of all words of tongue and pen, the saddest are: "It might have been"

Nov 17 '05 #3
billr wrote:
traditionally, I would declare my pointer OUTSIDE of the for loop (for
obvious reasons),
The only "obvious" reason for that would be if you need the pointer
*after* the for loop.
but whilst reviewing code produced by several "seasoned"
developers, their C# code does the opposite, for example:
"seasoned" programmers should avoid micro-optimization, especially
things like moving declarations outside loops to gain speed. The
compiler will remove the percieved overhead, even when not generating
optimized code.

A good way to make fast programs is:

1. use the right algorithms and data-structures
2. only "optimize" code if the profiler shows it is using much of the
run-time.
what I want to know is, yes, we are using a managed heap, but that doesn't
necessarily make that last bit of code any more acceptable does it?


The first bit of code is probably most "unacceptable", in both C, C++
and C#.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #4
> The only "obvious" reason for that would be if you need the pointer
*after* the for loop.
this is not the obvious reason to which I was alluding, but again, I could
quite simply be WRONG.

it is my belief that the following call does two things

MyObject *ptrObject = new MyObject();

1) heap space is found and allocated for an object of size __sizeof(MyObject)
2) the object is initialised at the location given by ptrObject

so, if I were to make this call inside a loop (of any kind), each time the
call is made, heap space is found and allocated, whereas should the decl be
made outside the loop, heap space is only allocated once, and the object is
only instantiated for each iteration.

Speed is not the issue here, but instead it is available resources. Am I
still barking up the wrong tree?

--
--

Of all words of tongue and pen, the saddest are: "It might have been"
"Helge Jensen" wrote:
billr wrote:
traditionally, I would declare my pointer OUTSIDE of the for loop (for
obvious reasons),


The only "obvious" reason for that would be if you need the pointer
*after* the for loop.
but whilst reviewing code produced by several "seasoned"
developers, their C# code does the opposite, for example:


"seasoned" programmers should avoid micro-optimization, especially
things like moving declarations outside loops to gain speed. The
compiler will remove the percieved overhead, even when not generating
optimized code.

A good way to make fast programs is:

1. use the right algorithms and data-structures
2. only "optimize" code if the profiler shows it is using much of the
run-time.
what I want to know is, yes, we are using a managed heap, but that doesn't
necessarily make that last bit of code any more acceptable does it?


The first bit of code is probably most "unacceptable", in both C, C++
and C#.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Nov 17 '05 #5


billr wrote:
it is my belief that the following call does two things

MyObject *ptrObject = new MyObject();

1) heap space is found and allocated for an object of size __sizeof(MyObject)
correct.
2) the object is initialised at the location given by ptrObject
correct.
so, if I were to make this call inside a loop (of any kind), each time the
call is made, heap space is found and allocated,
yes.
whereas should the decl be
made outside the loop, heap space is only allocated once,
No.

Whether the *declaration* of ptrObject is inside or outside the loop
does not affect heap-allocation. Operator new allocates heap for the object.

Note, that if SomeObj is not dependant on i, you could reuse the same
SomeObj instance, see below. Since you *do* construct a new instance
foreach i I will assume that SomeObj depends on i.

Your original example was:
SomeObj *ptrSomeObj;
for(int i = 0; i < iCount; ++i)
{ ptrSomeObj = new SomeObj(i);
^^^^^^^^^^^^^^ modified to add "i" ptrSomeObj->MethodOne();
delete ptrSomeObj;
}


Which allocates a SomeObj instance on the heap and constructs it using
SomeObj::Someobj(). You (probably correctly) delete ptrSomeObj when done
with it.

If you move the *declaration* of ptrSomeObj into the loop:

for(int i = 0; i < iCount; ++i)
{
SomeObj ptrSomeObj = new SomeObj(i);
ptrSomeObj->MethodOne();
delete ptrSomeObj;
}

The code has exactly the same semantics and behaviour, except that
ptrSomeObj does not have scope outside the for-loop.

The program (without delete):

for(int i = 0; i < iCount; ++i)
{
SomeObj ptrSomeObj = new SomeObj(i);
ptrSomeObj->MethodOne();
}

will *leak* a SomObj instance for each iteration.

The corresponding C# program is:

for ( int i = 0; i < iCount; ++i )
new SomeObj(i).MethodOne();

Which instantiates SomeObj foreach i. It does not leak, because the
garbage-collector will clean up.
and the object is
only instantiated for each iteration.
Objects in C++ are *allocated* and *constructed*. Allocation is done on
the stack or via (some form of) operator new. the default new (usually)
allocates on the heap.

All local variables are allocated on the stack:

T t;

allocates room for an instance of T on the stack.

T *t;

allocates room for a *pointer* to T on the stack.
Speed is not the issue here, but instead it is available resources. Am I
still barking up the wrong tree?


I would probably write the C++ code as:

for ( int i = 0; i < iCount; ++i )
SomeObj(i).MethodOne();

If your SomeObj does *not* depend on i (so MethodOne presumably does), I
would write:

{
SomeObj so;
for ( int i = 0; i < iCount; ++i )
so.MethodOne(i);
}

Both of which allocate SomeObj on the *stack*.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 17 '05 #6
billr wrote:
Now, as far as I'm aware, the equivalent code in C# is this:

SomeObj myObj;
for(int i = 0; i < iCount; ++i)
{
myObj = new SomeObj();
myObj.MethodOne();
}

Now the question comes ....

traditionally, I would declare my pointer OUTSIDE of the for loop (for
obvious reasons), but whilst reviewing code produced by several "seasoned"
developers, their C# code does the opposite, for example:

for(int i = 0; i < iCount; ++i)
{
SomeObj myObj = new SomeObj();
myObj.MethodOne();
}

what I want to know is, yes, we are using a managed heap, but that doesn't
necessarily make that last bit of code any more acceptable does it?

Or am I completely wrong.


Personally I was with you. In the Java world (circa 1.2) it was more
efficient to re-use the object pointer than create a new one each time.

A quick test here in C# using StringBuilder has shown that it makes sod
all difference.

I guess now that that appears to be the case I guess the latter is more
preferrable because the object within the loop is kept within that scope.

Cheers
Jimbo

Nov 17 '05 #7
That has helped me to realise what I have been saying, and obviously it turns
out that what I'm saying is complete nonsense!

I think I've been saying something like this :

If you declare your object outside the loop, when you instantiate the object
for each iteration within the loop, the address of the new object will be the
same as the address of the previous object. (doh!) obviously that won't work!

Thanks again (I did say it was a noddy question didn't I?)

:o)
--
--

Of all words of tongue and pen, the saddest are: "It might have been"
"Helge Jensen" wrote:


billr wrote:
it is my belief that the following call does two things

MyObject *ptrObject = new MyObject();

1) heap space is found and allocated for an object of size __sizeof(MyObject)


correct.
2) the object is initialised at the location given by ptrObject


correct.
so, if I were to make this call inside a loop (of any kind), each time the
call is made, heap space is found and allocated,


yes.
whereas should the decl be
made outside the loop, heap space is only allocated once,


No.

Whether the *declaration* of ptrObject is inside or outside the loop
does not affect heap-allocation. Operator new allocates heap for the object.

Note, that if SomeObj is not dependant on i, you could reuse the same
SomeObj instance, see below. Since you *do* construct a new instance
foreach i I will assume that SomeObj depends on i.

Your original example was:
>>> SomeObj *ptrSomeObj;
>>> for(int i = 0; i < iCount; ++i)
>>> { ptrSomeObj = new SomeObj(i);
^^^^^^^^^^^^^^ modified to add "i" >>> ptrSomeObj->MethodOne();
>>> delete ptrSomeObj;
>>> }


Which allocates a SomeObj instance on the heap and constructs it using
SomeObj::Someobj(). You (probably correctly) delete ptrSomeObj when done
with it.

If you move the *declaration* of ptrSomeObj into the loop:

for(int i = 0; i < iCount; ++i)
{
SomeObj ptrSomeObj = new SomeObj(i);
ptrSomeObj->MethodOne();
delete ptrSomeObj;
}

The code has exactly the same semantics and behaviour, except that
ptrSomeObj does not have scope outside the for-loop.

The program (without delete):

for(int i = 0; i < iCount; ++i)
{
SomeObj ptrSomeObj = new SomeObj(i);
ptrSomeObj->MethodOne();
}

will *leak* a SomObj instance for each iteration.

The corresponding C# program is:

for ( int i = 0; i < iCount; ++i )
new SomeObj(i).MethodOne();

Which instantiates SomeObj foreach i. It does not leak, because the
garbage-collector will clean up.
and the object is
only instantiated for each iteration.


Objects in C++ are *allocated* and *constructed*. Allocation is done on
the stack or via (some form of) operator new. the default new (usually)
allocates on the heap.

All local variables are allocated on the stack:

T t;

allocates room for an instance of T on the stack.

T *t;

allocates room for a *pointer* to T on the stack.
Speed is not the issue here, but instead it is available resources. Am I
still barking up the wrong tree?


I would probably write the C++ code as:

for ( int i = 0; i < iCount; ++i )
SomeObj(i).MethodOne();

If your SomeObj does *not* depend on i (so MethodOne presumably does), I
would write:

{
SomeObj so;
for ( int i = 0; i < iCount; ++i )
so.MethodOne(i);
}

Both of which allocate SomeObj on the *stack*.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Nov 17 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Torsten Mohr | last post: by
3 posts views Thread by Piotre Ugrumov | last post: by
2 posts views Thread by fhadian1 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.