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

G

Guest

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.
 
G

Guest

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!)
 
O

Octavio Hernandez

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
 
H

Helge Jensen

billr said:
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#.
 
G

Guest

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?
 
H

Helge Jensen

billr said:
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:
ptrSomeObj = new SomeObj(i);
^^^^^^^^^^^^^^ modified to add "i"
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*.
 
J

Jimbo

billr said:
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
 
G

Guest

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?)

:blush:)
 

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

Top