Why people use "new" & "delete" too much?!!

M

Medvedev

i see serveral source codes , and i found they almost only use "new"
and "delete" keywords to make they object.
Why should i do that , and as i know the object is going to be destroy
by itself at the end of the app

for example:
class test
{
public:
int x;
}

int main(int argc, char **argv)
{
test *n= new test;
.
.
...
delete n;

return 0;
}
i know that the object created this way is in the heap which have much
memory than stack but why they always define objects that way , why
not just say "test n" and the object will be destroyed by itself at
the end of the program! , instead of using "new" and maybe u will
forget to "delete" at the end
 
R

red floyd

Medvedev said:
i see serveral source codes , and i found they almost only use "new"
and "delete" keywords to make they object.
Why should i do that , and as i know the object is going to be destroy
by itself at the end of the app

for example:
class test
{
public:
int x;
}

int main(int argc, char **argv)
{
test *n= new test;
.
.
...
delete n;

return 0;
}
i know that the object created this way is in the heap which have much
memory than stack but why they always define objects that way , why
not just say "test n" and the object will be destroyed by itself at
the end of the program! , instead of using "new" and maybe u will
forget to "delete" at the end

Several reasons.

1. They're coming from Java and they don't know any better
2. They're storing polymorphic objects inside containers
3. They need the lifetime of the object to exceed the scope in which
it was declared.
 
M

Medvedev

Several reasons.

1. They're coming from Java and they don't know any better
2. They're storing polymorphic objects inside containers
3. They need the lifetime of the object to exceed the scope in which
it was declared.

how u can use object after it's scope ends!!
 
S

Somebody

class CFoo
{
};

CFoo* GetFoo()
{
return new CFoo;
}

Still, I agree with you, people over use new and delete. I recently saw a
class library written in C++ that tried to be all C#'ish and required you to
write code like:

classa->InsertItem(new classB(param1));
classa->InsertItem(new classC(param2));

*STUPID*... if your code is too stupid to decide what kind of object should
be created (and keep in mind, I could see doing this for user defined
objects, but these were all internal objects), then why would you expect a
user of your class to?

Plus, that hurts performance.
 
I

Ian Collins

Medvedev said:
how u can use object after it's scope ends!!

I don't know about "u", but the rest of us don't.

A pointer to a dynamically allocated object can be returned from the
function that created it, or declared in an outer scope and assigned in
an inner one.
 
A

acehreli

Still, I agree with you, people over use new and delete. I recently saw a
class library written in C++ that tried to be all C#'ish and required you to
write code like:

classa->InsertItem(new classB(param1));
classa->InsertItem(new classC(param2));

*STUPID*...

It's not obvious what you say that. Is it because the dynamic objects
are not handed to smart pointers right away? Or do you propose
something like the following?

classa->InsertItem(&classB(param1));
classa->InsertItem(&classC(param2));

You realize that the temporaries would be terminated too soon to be
useful?
Plus, that hurts performance.

Compared to what? If it's needed, then there is no alternative.

Ali
 
P

phlip

Medvedev said:
i see serveral source codes , and i found they almost only use "new"
and "delete" keywords to make they object.

If you write an OO program, you will find yourself needing a base class pointer
that points to a derived class. (That is the very goal of "OO" - to override
some critical method into that derived class.)

Otherwise, you could construct an object on the stack, use it, and let it
destroy when its method returns.

Because you need dynamically sized and typed objects, you must sometimes new them.
Why should i do that , and as i know the object is going to be destroy
by itself at the end of the app

You should code as if you don't know that. Always clean up after yourself. One
good way is with "smart pointers".
for example:
class test
{
public:
int x;
}

int main(int argc, char **argv)
{
test *n= new test;
.
.
...
delete n;

return 0;
}
i know that the object created this way is in the heap which have much
memory

Not necessarily. On modern architectures with virtual memory, both the heap and
stack can grow arbitrarily.
> than stack but why they always define objects that way , why
not just say "test n" and the object will be destroyed by itself at
the end of the program! , instead of using "new" and maybe u will
forget to "delete" at the end

Because that's one of the many things C++ will let you do that are sloppy. Don't
do any of them, because any one of them could come back to bite you on the butt.

For example, you could refactor the n = new test and move it inside a working
loop. Then the loop would silently leak (virtual!) memory. You would not notice
until your program ran for hours, and got very slow.
 
S

Salt_Peter

how u can use object after it's scope ends!!

Thats not what he stated. The object is _declared_ in a finite scope.
If you allocate the object on the heap, it's lifetime no longer relies
on the declaring scope.

Basicly, new and new[] transfers the responsability to you, the
programmer, to delete and delete[].

Is using new and new[] a good habit? no, its not.
You'll find C++ programmers to be retiscent in using it and would
rather rely on a smart pointer if heap allocation is indeed required.
Java programmers don't really have a choice but in C++ an automatic
variable should and usually is the default.

Generally speaking, if you see new and new[], you aren't reading a
programmer who has his roots in modern C++. Allocating on the heap
what should be automatic is frowned upon here.

And the reason for that is because smart pointers have much to offer
as long as you know their limitations.
Good examples of those are std::auto_ptr and boost::shared_ptr to name
a few.
 
S

Somebody

It's not obvious what you say that. Is it because the dynamic objects
are not handed to smart pointers right away? Or do you propose
something like the following?

classa->InsertItem(&classB(param1));
classa->InsertItem(&classC(param2));

You realize that the temporaries would be terminated too soon to be
useful?


Compared to what? If it's needed, then there is no alternative.

Ali

Well, let me de-anonimize the code a bit :)...

They had a bunch of stuff like:

ctrl->InsertItem(new ButtonTypeA(param1, param2));
ctrl->InsertItem(new ButtonTypeB(param3, param4));
ctrl->InsertItem(new ButtonTypeC(param4, param5));

So they had a UI control, and they were inserting items into it. ButtonTypeX
was a class *the class library* defined... not something that a *user* of
the class library would (or could) define.

What I was saying... was I failed to see why I should do the dirty work for
the library and not only determine what class to use, but also to allocate
it for them. They should determine whether to create the internal
ButtonTypeA, ButtonTypeB, ButtonTypeC, etc. in some other way (like a param
for example)... so I'd rather see something like:

ctrl->InsertItem(param1, param2);
ctrl->InsertItem(param3, param4);
ctrl->InsertItem(param4, param5);

or

ctrl->InsertButtonTypeA(param1, param2);
ctrl->InsertButtonTypeB(param3, param4);
ctrl->InsertButtonTypeC(param4, param5);

or

ctrl->InsertItem(TYPE_A, param1, param2);
ctrl->InsertItem(TYPE_B, param3, param4);
ctrl->InsertItem(TYPE_C, param4, param5);

Like other posters said, that style of code is C#'ish or Java'ish... it is
not typical C++ style. Unless you are doing some type of class factory type
thing.

Allocating memory is slow... which is why this particular UI library was
commonly regarded as having poor performance.
 
J

James Kanze

Several reasons.
1. They're coming from Java and they don't know any better
2. They're storing polymorphic objects inside containers

Not just storing them inside containers. I've a couple of
places where I've code something like:

std::auto_ptr< Base > obj(
someCondition
? static_cast< Base* >( new D1 )
: static_cast< Base* >( new D2 ) ) ;

It's not that common, however.
3. They need the lifetime of the object to exceed the scope in which
it was declared.

Often, the last two reasons go together: although there's no
formal link between them, in practice, polymorphic objects tend
to have arbitrary lifetimes.

Note that you normally would prefer copying an object to
extending its lifetime, if the object supports copy.
 
J

James Kanze

On Jul 5, 11:59 am, red floyd <[email protected]> wrote:

[...]
how u can use object after it's scope ends!!

Objects don't have scope, they have lifetime. Scope concerns
the visibility of a declaration (and is linked with the
structure of the program). Lifetime concerns when the object
comes into and goes out of being. C++ defines several different
types of lifetime, some linked to scope (e.g. automatic), and
others not (e.g. dynamic). If you create an object with new, it
has dynamic lifetime, and exists until you delete it. Which
could be somewhere else entirely.
 
J

James Kanze

Well, let me de-anonimize the code a bit :)...
They had a bunch of stuff like:
ctrl->InsertItem(new ButtonTypeA(param1, param2));
ctrl->InsertItem(new ButtonTypeB(param3, param4));
ctrl->InsertItem(new ButtonTypeC(param4, param5));
So they had a UI control, and they were inserting items into
it. ButtonTypeX was a class *the class library* defined... not
something that a *user* of the class library would (or could)
define.

But he could almost certainly define a class which derived from
it, and use that instead.
What I was saying... was I failed to see why I should do the
dirty work for the library and not only determine what class
to use, but also to allocate it for them. They should
determine whether to create the internal ButtonTypeA,
ButtonTypeB, ButtonTypeC, etc. in some other way (like a param
for example)...

It's very likely that all three calls above invoke the same
InsertItem. Even if they don't, it's almost certain that the
user code could derive from the different ButtonType's, and pass
an instance of the derived class, rather than the base class.
so I'd rather see something like:
ctrl->InsertItem(param1, param2);
ctrl->InsertItem(param3, param4);
ctrl->InsertItem(param4, param5);

ctrl->InsertButtonTypeA(param1, param2);
ctrl->InsertButtonTypeB(param3, param4);
ctrl->InsertButtonTypeC(param4, param5);

ctrl->InsertItem(TYPE_A, param1, param2);
ctrl->InsertItem(TYPE_B, param3, param4);
ctrl->InsertItem(TYPE_C, param4, param5);
Like other posters said, that style of code is C#'ish or
Java'ish... it is not typical C++ style.

It's very typical C++ where polymorphism and arbitrary lifetime
is involved, which is almost certainly the case here.

C++ is a multi-paradigm language. There are cases when the
above paradigm is appropriate, C++ supports it, and it should be
used in such cases.
Unless you are doing some type of class factory type
thing.
Allocating memory is slow... which is why this particular UI
library was commonly regarded as having poor performance.

Practically speaking, things like buttons in a GUI must have
arbitrary lifetime; they can't be automatic variables. So if
you don't do the new, the library must. And you immediately
loose the flexibility of deriving from the object. And of
course, things like Button's typically also have identity; if
you attach an event handler to one instance, but a copy receives
the event, then your code isn't going to work.
 
P

Pascal J. Bourguignon

Somebody said:
Allocating memory is slow... which is why this particular UI library was
commonly regarded as having poor performance.

Only in C++, because there's no garbage collector. In languages with
automatic memory management, allocating is free.
 
K

Krice

why not just say "test n" and the object will be destroyed

Because you never wrote anything else than hello world
programs so you don't have a fucking clue what you are
talking about.
 
D

Darío Griffo

Yannick said:
Under some
circumstances, it can be orders of magnitude faster than C++
explicit memory management but it certainly isn't free and things can
happen if you get out of a particualr set of "some circumstances"

This is interesting. What cases?
 
J

Jerry Coffin

Only in C++, because there's no garbage collector. In languages with
automatic memory management, allocating is free.

While it's apparent that you're much more interested in advocacy than
accuracy, could you at least attempt to maintain some _minimal_ level of
accuracy? Allocating is _never_ free. Furthermore, automatic memory
management doesn't necessarily even make it cheap.

There are garbage collectors (those that compact the heap) that make
allocation cheap. There are others (that don't compact the heap) with
which allocation can still be quite expensive.

On the other side, there are manual allocators (those that do
compaction) that make allocation cheap. There are others (those that
don't do compaction) with which allocation can be quite expensive.

The _overall_ cost of a full cycle of allocating and freeing memory is
slightly lower (on average) with manually controlled allocators than
with automatically controlled ones -- but there's enough overlap between
the two that the average means virtually nothing. You need to know quite
a bit about usage patterns and the exact implementations of the manual
and automatic memory managers in question before you can make any
meaningful prediction about their relative speed under specific
circumstances. Having done that, you still know next to nothing about
even slightly different circumstances -- generalizing the results is
very difficult.
 
P

Pascal J. Bourguignon

Jerry Coffin said:
While it's apparent that you're much more interested in advocacy than
accuracy, could you at least attempt to maintain some _minimal_ level of
accuracy? Allocating is _never_ free. Furthermore, automatic memory
management doesn't necessarily even make it cheap.

There are garbage collectors (those that compact the heap) that make
allocation cheap. There are others (that don't compact the heap) with
which allocation can still be quite expensive.

On the other side, there are manual allocators (those that do
compaction) that make allocation cheap. There are others (those that
don't do compaction) with which allocation can be quite expensive.

The _overall_ cost of a full cycle of allocating and freeing memory is
slightly lower (on average) with manually controlled allocators than
with automatically controlled ones -- but there's enough overlap between
the two that the average means virtually nothing. You need to know quite
a bit about usage patterns and the exact implementations of the manual
and automatic memory managers in question before you can make any
meaningful prediction about their relative speed under specific
circumstances. Having done that, you still know next to nothing about
even slightly different circumstances -- generalizing the results is
very difficult.

Of course. I just meant to shatter the notion that new and new[] must
be slow. There are implementations where allocation is fast (a
pointer increment and a test). All right, some time is traded in the
deallocation or garbage collection, and you can always find a worse
case situation. The point is that a program with lots of new is not
bad per se.
 
J

James Kanze

Sorry, it isn't free.
The performance/cost characteristic of allocating and
releasing memory in an automatic memory managed language is
different. Under some circumstances, it can be orders of
magnitude faster than C++ explicit memory management but it
certainly isn't free and things can happen if you get out of a
particular set of "some circumstances"

Well, the *allocation* can be very, very cheap---two or three
machine instructions. And if the program doesn't run long
enough to trigger the collector, it will be about as close to
free as you can get.

More realistically, of course, I agree with your evaluation.
The total cost of allocating and freeing the memory can be
signficantly less, or significantly more, or (most of the time)
something more or less similar. The cost can also come at a
less convenient moment, or a more convenient moment, as well,
depending on the application. (GUI applications, for example,
work very well with garbage collection, because you can usually
arrange for almost all of the cost to occur when you'd otherwise
be waiting for an event.)

Where garbage collection is always a win is in development time
and program security and robustness.
 
J

Jerry Coffin

[ ... ]
Of course. I just meant to shatter the notion that new and new[] must
be slow. There are implementations where allocation is fast (a
pointer increment and a test). All right, some time is traded in the
deallocation or garbage collection, and you can always find a worse
case situation. The point is that a program with lots of new is not
bad per se.

You have argued that it's not necessarily _slow_. While you've provided
little real evidence of that, I'm not going to argue the point, because
even when/if the allocation itself is slow, a program can use it heavily
and still run at a perfectly acceptable speed.

Pointers are the data structure equivalent of the GOTO. What end up as
gotos (jumps) in assembly language should normally be hidden, with
what's visible being only high level block structures. Likewise,
pointers should typically be hidden, used to implement high level block
structures.

Programs where there's a lot of (visible) use of new, rather than most
use being hidden inside the implementation of higher level structures
aren't _necessarily_ evil -- but it's definitely a _strong_ indication
of a likely problem.
 
J

Jerry Coffin

(e-mail address removed)>, (e-mail address removed)
says...

[ ... ]
Where garbage collection is always a win is in development time
and program security and robustness.

Always...except when it's not.
 

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

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top