473,402 Members | 2,053 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

simple delete question

Hi,

I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.

I'd apprecitate any clarification and suggestions for rewriting the
below properly.

Thanks,
cpp

PS: The Char class below is used to store a pixel representation of a
character for display. A character in this context is simply a
collection of points.

#include <vector>
#include "Point.h"

class Char {
private:
char _ch;
std::vector<Point> _pixelPoints;
public:
Char(char);
~Char();
void addPoint(int, int);
std::vector<Point>& const getPixelPoints();
char getChar() {return _ch;}
};

Char::Char(char ch) :
_ch(ch)
{ }

Char::~Char() {
std::vector<Point>::iterator iter;
for (iter=_pixelPoints.begin(); iter!=_pixelPoints.end();
iter++)
delete iter;
}

void Char::addPoint(int x, int y) {
_pixelPoints.push_back(*( new Point(x,y) ));
}

std::vector<Point>& const Char::getPixelPoints() {
return _pixelPoints;
}
Jul 22 '05 #1
16 1988

"cppaddict" <he***@hello.com> wrote in message
news:n4********************************@4ax.com...
Hi,

I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.
What you are doing wrong is using new and delete at all. There seems to be
an epidemic of needless use of new on this group at the moment.

Corrections below.

I'd apprecitate any clarification and suggestions for rewriting the
below properly.

Thanks,
cpp

PS: The Char class below is used to store a pixel representation of a
character for display. A character in this context is simply a
collection of points.

#include <vector>
#include "Point.h"

class Char {
private:
char _ch;
std::vector<Point> _pixelPoints;
public:
Char(char);
~Char();
void addPoint(int, int);
std::vector<Point>& const getPixelPoints();
char getChar() {return _ch;}
};

Char::Char(char ch) :
_ch(ch)
{ }

Char::~Char() {
std::vector<Point>::iterator iter;
for (iter=_pixelPoints.begin(); iter!=_pixelPoints.end();
iter++)
delete iter;
}
Don't need the destructor, remove it.

void Char::addPoint(int x, int y) {
_pixelPoints.push_back(*( new Point(x,y) ));
Don't need to use new

_pixelPoints.push_back(Point(x,y));
}

std::vector<Point>& const Char::getPixelPoints() {
return _pixelPoints;
}


Should be fine now.

john
Jul 22 '05 #2

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2h************@uni-berlin.de...

"cppaddict" <he***@hello.com> wrote in message
news:n4********************************@4ax.com...
Hi,

I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.


What you are doing wrong is using new and delete at all. There seems to be
an epidemic of needless use of new on this group at the moment.


I'm curious as to what led you to use new at all. After all there are no
pointers in your code, so why did you consider using new?

Seems to be happening a lot lately so I'm interested in what makes new and
delete (and pointers generally) so attractive to newbies. Maybe you can
explain.

john
Jul 22 '05 #3
cppaddict wrote:
I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.


A question: Why you "delete" something that you do not "new" ?

In addPoint you add:
*( new Point(x,y) )
and not:
new Point(x,y)
so you cannot delete it.

Probably you can rewrite your addPoint as:

void Char::addPoint(int x, int y) {
Point * p = new Point(x,y);
_pixelPoints.push_back(*p));
delete p;
}

and avoid to delete anything in ~Char().

Just my 2 cents...

- Dario
Jul 22 '05 #4

"Dario (drinking coï¬?ee in the oï¬fceâ?¦)" <da***@despammed.com> wrote in
message news:c8**********@grillo.cs.interbusiness.it...
cppaddict wrote:
I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.


A question: Why you "delete" something that you do not "new" ?

In addPoint you add:
*( new Point(x,y) )
and not:
new Point(x,y)
so you cannot delete it.

Probably you can rewrite your addPoint as:

void Char::addPoint(int x, int y) {
Point * p = new Point(x,y);
_pixelPoints.push_back(*p));
delete p;
}


That works but why?? Needless use of new, inefficient and error prone.

_pixelPoints.push_back(Point(x,y));

What's so hard about the above that newbies fail to use it?

john
Jul 22 '05 #5
John Harrison wrote:
"Dario (drinking coï¬?ee in the oï¬fceâ?¦)" <da***@despammed.com> wrote in
message news:c8**********@grillo.cs.interbusiness.it...
cppaddict wrote:
I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.
A question: Why you "delete" something that you do not "new" ?

In addPoint you add:
*( new Point(x,y) )
and not:
new Point(x,y)
so you cannot delete it.

Probably you can rewrite your addPoint as:

void Char::addPoint(int x, int y) {
Point * p = new Point(x,y);
_pixelPoints.push_back(*p));
delete p;
}


That works but why?? Needless use of new, inefficient and error prone.

_pixelPoints.push_back(Point(x,y));


Good point.
What's so hard about the above that newbies fail to use it?


The explanation (at least for me) is the fact that I'm used
(since many years) to write in Java, where the only way to create
a new Object is via the "new" operator.
So (at least for me) the natural way is always
new Point(x, y)

But definitively in C++ the example mu be written as you said.

- Dario
Jul 22 '05 #6

"Dario (drinking co?ee in the o?ce.)" <da***@despammed.com> wrote in message
news:c8**********@balena.cs.interbusiness.it...
John Harrison wrote:
"Dario (drinking coï¬?ee in the oï¬fceâ?¦)" <da***@despammed.com> wrote in message news:c8**********@grillo.cs.interbusiness.it...
cppaddict wrote:

I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.

A question: Why you "delete" something that you do not "new" ?

In addPoint you add:
*( new Point(x,y) )
and not:
new Point(x,y)
so you cannot delete it.

Probably you can rewrite your addPoint as:

void Char::addPoint(int x, int y) {
Point * p = new Point(x,y);
_pixelPoints.push_back(*p));
delete p;
}
That works but why?? Needless use of new, inefficient and error prone.

_pixelPoints.push_back(Point(x,y));


Good point.


Ho ho!
What's so hard about the above that newbies fail to use it?


The explanation (at least for me) is the fact that I'm used
(since many years) to write in Java, where the only way to create
a new Object is via the "new" operator.
So (at least for me) the natural way is always
new Point(x, y)


Yes that explains some of it. But I definitely get the impression that
non-Java programmers also make similar mistakes.

john
Jul 22 '05 #7

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2h************@uni-berlin.de...

"Dario (drinking co?ee in the o?ce.)" <da***@despammed.com> wrote in message news:c8**********@balena.cs.interbusiness.it...
John Harrison wrote:
"Dario (drinking coï¬?ee in the oï¬fceâ?¦)" <da***@despammed.com>
wrote
[snip]
What's so hard about the above that newbies fail to use it?


The explanation (at least for me) is the fact that I'm used
(since many years) to write in Java, where the only way to create
a new Object is via the "new" operator.
So (at least for me) the natural way is always
new Point(x, y)


Yes that explains some of it. But I definitely get the impression that
non-Java programmers also make similar mistakes.


When I joined my current employer 2 years ago, our product was rife with
unnecessary new/delete usage. My predecessor along with most of the other
employees are long time C programmers. At least they did use new/delete
rather than malloc/free.

Jeff F
Jul 22 '05 #8
John Harrison wrote:

Seems to be happening a lot lately so I'm interested in what makes new and
delete (and pointers generally) so attractive to newbies. Maybe you can
explain.


Java pollution.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #9
I'm not sure that you understand what happens when you add something to
a vector. The vector contructs a copy of the object you pass it and
stores this copy. This is why you do not need to delete what you have
added.

This might seem like it will be slow and well it could be. To get around
this you could store a vector of pointers vector<Point*> now it will
make a copy of your pointer not the object. Now you would have to delete
what you have added to your vector.

In java you could view all you objects as pointers and that is way you
need a new and also why you can assing them the value nil.

Stefan

In <n4********************************@4ax.com> cppaddict wrote:
Hi,

I am deleting some objects created by new in my class destructor, and
it is causing my application to error at runtime. The code below
compiles ok, and also runs fine if I remove the body of the
destructor. So I think I am somehow using delete incorrectly, but I'm
not sure exaclty what I'm doing wrong.

I'd apprecitate any clarification and suggestions for rewriting the
below properly.

Thanks,
cpp

PS: The Char class below is used to store a pixel representation of a
character for display. A character in this context is simply a
collection of points.

#include <vector>
#include "Point.h"

class Char {
private:
char _ch;
std::vector<Point> _pixelPoints;
public:
Char(char);
~Char();
void addPoint(int, int);
std::vector<Point>& const getPixelPoints();
char getChar() {return _ch;}
};

Char::Char(char ch) :
_ch(ch)
{ }

Char::~Char() {
std::vector<Point>::iterator iter;
for (iter=_pixelPoints.begin(); iter!=_pixelPoints.end();
iter++)
delete iter;
}

void Char::addPoint(int x, int y) {
_pixelPoints.push_back(*( new Point(x,y) ));
}

std::vector<Point>& const Char::getPixelPoints() {
return _pixelPoints;
}

Jul 22 '05 #10

"Stefan Pantos" <st***********@chem.ox.ac.uk> wrote in message
news:20********************@news.ox.ac.uk...
I'm not sure that you understand what happens when you add something to
a vector. The vector contructs a copy of the object you pass it and
stores this copy. This is why you do not need to delete what you have
added.

This might seem like it will be slow and well it could be. To get around
this you could store a vector of pointers vector<Point*> now it will
make a copy of your pointer not the object. Now you would have to delete
what you have added to your vector.


Seems unlikely in this case. Presumably Point is some small class (two ints
perhaps). Dynamically allocating a large number of small objects is a
notorious inefficiency. By constrast copying small objects is going to be
much more efficient.

If you had a very large object, then the cost of copying might exceed the
cost of allocating it, but even in that case you would normally use a smart
pointer rather than a raw pointer.

john
Jul 22 '05 #11
>I'm curious as to what led you to use new at all. After all there are no
pointers in your code, so why did you consider using new?

Seems to be happening a lot lately so I'm interested in what makes new and
delete (and pointers generally) so attractive to newbies. Maybe you can
explain.


Thank you all for the clarification.

John,

To answer your question, my erroneous thought process was simply this:
Since the number of Points in a Char object varies, that means the
memory must be dynamically allocated at runtime, and therefore that
means I will have to use the new operator. Or, to break it down:

Don't know how many Points are in a Char //step 1 in my reasoning
implies==>dynamic allocation //step 2
imples==> use new operator //step 3

Correct me if I'm wrong, but looking back at the code now it seems to
me that my logical error was in step 2.

There was an additional consideration too, which someone else
mentioned, and which you can't see from the posted code, which I
simplified in order to give focus to my question. That additional
consideraton was my belief that the cost of copying an object (even a
small one) was more than the cost of dynamic allocation -- indeed, I
was not aware that dynamic allocation had a high cost at all.

Originally, the signature of addPoint() looked like this:

void addPoint(Point& const);

Thus I believed that I was efficiently creating a new Point object, as
well as avoiding any overhead involved in copying an object (since I
was passing by reference). Please let me know if there are additional
logical erros in THAT statement.

Finally, you mention that even if the Point object was large, it would
be better to use smart pointers rather than to store a vector of
pointers which you delete yourself. Why is this so? Wouldn't the
cost of those things be the same?

Thanks again,
cpp
Jul 22 '05 #12
>
That works but why?? Needless use of new, inefficient and error prone.

_pixelPoints.push_back(Point(x,y));

What's so hard about the above that newbies fail to use it?


I think it might be that this looks like a direct call to a class'
constructor, which they are told is not allowed. In reality it's the
construction of a temporary object, and that object is then copied by the
push_back function, and the temporary destroyed. (Although I think the
compiler is allowed to omit the temporary I think, and directly initialize
the copy used by push_back...right?)

In any case, new C++ coders are taught, in general, that there are only two
ways to construct an object. One is using a simple "static" declaration, as
in

Point p;

or,

Point p(4,5);

and the other is to dynamically allocate it, as in

Point* p;
....
p = new Point(4,5);

or

Point p = new Point(4,5);

I don't recall ever seeing anyone do it like this

foo(Point(4,5));

until I'd been watching this newsgroup for a while. It doesn't seem to fit
with either of the "two methods" we we're originally taught, and you have to
admit it's a little obscure until you've actually used it yourself. It's
not that it's hard to grasp...just that nobody tells them it's legal (and
useful)!

Maybe we simply need to teach newbies this as a "third" method of
constructing an object?

-Howard


Jul 22 '05 #13

"Howard" <al*****@hotmail.com> wrote in message
news:HQ*******************@bgtnsc05-news.ops.worldnet.att.net...

That works but why?? Needless use of new, inefficient and error prone.

_pixelPoints.push_back(Point(x,y));

What's so hard about the above that newbies fail to use it?


I think it might be that this looks like a direct call to a class'
constructor, which they are told is not allowed. In reality it's the
construction of a temporary object, and that object is then copied by the
push_back function, and the temporary destroyed. (Although I think the
compiler is allowed to omit the temporary I think, and directly initialize
the copy used by push_back...right?)


Maybe but it doesn't explain why new is used. The following avoids using any
temporaries.

Point tmp(x, y);
_pixelPoints.push_back(tmp);

Maybe it's a lack of confidence with C++ value semantics. A newbie might
worry that tmp is going to go out of scope and when that happens the value
on the vector will be invalidated in some way.

john
Jul 22 '05 #14

"cppaddict" <he***@hello.com> wrote in message
news:kh********************************@4ax.com...
I'm curious as to what led you to use new at all. After all there are no
pointers in your code, so why did you consider using new?

Seems to be happening a lot lately so I'm interested in what makes new anddelete (and pointers generally) so attractive to newbies. Maybe you can
explain.
Thank you all for the clarification.

John,

To answer your question, my erroneous thought process was simply this:
Since the number of Points in a Char object varies, that means the
memory must be dynamically allocated at runtime, and therefore that
means I will have to use the new operator. Or, to break it down:

Don't know how many Points are in a Char //step 1 in my reasoning
implies==>dynamic allocation //step 2
imples==> use new operator //step 3

Correct me if I'm wrong, but looking back at the code now it seems to
me that my logical error was in step 2.


I think the conceptual error is that you are confusing the container with
the contained objects. It is true that the container (i.e. the vector) has
to use new (or something like it) in order hold a varying number of Points.
But that use of new is in the vector code which has already been written
for you, it not necessary to use it in your code.

Consider a vector of integers, would you have tried to allocate each integer
using new, like this?

vector<int> x;
x.push_back(*(new int(5));

Or would you have just written

vector<int> x;
x.push_back(5);

There was an additional consideration too, which someone else
mentioned, and which you can't see from the posted code, which I
simplified in order to give focus to my question. That additional
consideraton was my belief that the cost of copying an object (even a
small one) was more than the cost of dynamic allocation -- indeed, I
was not aware that dynamic allocation had a high cost at all.
No, definitely not, the cost of allocating large numbers of small objects is
going to greatly exceed the cost of copying those objects.

Originally, the signature of addPoint() looked like this:

void addPoint(Point& const);

Thus I believed that I was efficiently creating a new Point object, as
well as avoiding any overhead involved in copying an object (since I
was passing by reference). Please let me know if there are additional
logical erros in THAT statement.
Right, so you were coding like this?

Char c;
c.addPoint(*(new Point(x, y)));

You are right that in general using a const reference is a good idea to
avoid unecessary copies. But again the same change should be made

Char c;
c.addPoint(Point(x, y));


Finally, you mention that even if the Point object was large, it would
be better to use smart pointers rather than to store a vector of
pointers which you delete yourself. Why is this so? Wouldn't the
cost of those things be the same?


Similar, in fact the smart pointer will be fractionally more expensive. The
point of smart pointers is that they are much less error prone. Because a
smart pointer takes care of the burden of deleteing an object for you its
impossible to forget to delete a pointer (thus causing a memory leak) or
delete a pointer twice (probably crashing your program).

john
Jul 22 '05 #15
>No, definitely not, the cost of allocating large numbers of small objects is
going to greatly exceed the cost of copying those objects.
Good to know.

You are right that in general using a const reference is a good idea to
avoid unecessary copies. But again the same change should be made

Char c;
c.addPoint(Point(x, y));
Yet the compiler won't let me create a vector of Point references.
That is, the following is not allowed:

std::vector<Point&> vectorOfPointReferences;

So it seems there is no way to avoid making copies of Point when you
add it to the vector. That is, the Point argument to push_back will
always have to be created and then copied to the vector. Is there any
way to avoid this unnecessary copying, even if is less burdensome than
unnessary allocating. It seems that there should be. Am I still
missing something?
Similar, in fact the smart pointer will be fractionally more expensive. The
point of smart pointers is that they are much less error prone. Because a
smart pointer takes care of the burden of deleteing an object for you its
impossible to forget to delete a pointer (thus causing a memory leak) or
delete a pointer twice (probably crashing your program).


Good point. I will keep it in mind.

Thanks again,
cpp
Jul 22 '05 #16

"cppaddict" <he***@hello.com> wrote in message
news:37********************************@4ax.com...
No, definitely not, the cost of allocating large numbers of small objects isgoing to greatly exceed the cost of copying those objects.


Good to know.

You are right that in general using a const reference is a good idea to
avoid unecessary copies. But again the same change should be made

Char c;
c.addPoint(Point(x, y));


Yet the compiler won't let me create a vector of Point references.
That is, the following is not allowed:

std::vector<Point&> vectorOfPointReferences;

So it seems there is no way to avoid making copies of Point when you
add it to the vector. That is, the Point argument to push_back will
always have to be created and then copied to the vector. Is there any
way to avoid this unnecessary copying, even if is less burdensome than
unnessary allocating. It seems that there should be. Am I still
missing something?


Its part of the design of STL containers that they hold copies of the
objects that are added to them. Anything else would be virtually unusable.

vector<string> vec;
for (...)
{
string s = "123";
vec.push_back(s);
s = "abc"; // s modified here, should that also affect vec?
} // s destroyed here, should that affect vec?

Fortunately the answer to both questions is no. And that is only possible
because vec has taken a copy of the original string s.

john
Jul 22 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Patchwork | last post by:
Hi Everyone, Please take a look at the following (simple and fun) program: //////////////////////////////////////////////////////////////////////////// ///////////// // Monster Munch, example...
7
by: cppaddict | last post by:
The following code compiles but errors at runtime: int main() { std::string* str; str->insert(0,"test"); std::cout << *str; } Why does this not work? How can I fix it?
13
by: LRW | last post by:
Having a problem getting a onSubmit function to work, to where it popsup a confirmation depending on which radiobutton is selected. Here's what I have: function checkdel() { if...
3
by: simon | last post by:
I get from database something like this: DAY HOUR PRICE --------------------------------------------- MONDAY 10 100 MONDAY 11 ...
4
by: Andy | last post by:
Sorry if this is too simple to post… We’re about to develop a web site where a couple of users want to administer users access. Users access via a username and password. Assuming that these...
1
by: E.T. Grey | last post by:
I have been busting my nut over this for pretty much most of the day and it is driving me nuts. I posted this to an mySQL ng yesterday and I have not had any response (I'm pulling my hair out...
9
by: Odd Bjørn Andersen | last post by:
I want to delete some rows from a table (TAB1), but only those rows which has a match in antother table (TAB2). Something like this: TAB1: col1, col2, ..... TAB2, col1, col2,...... There are...
3
by: asianmuscle | last post by:
Hi I am relearning datastructure... but got kinda stuck in a basic delete node operation. what it does is to delete the first node it finds when the item is equal the input item. the end result is...
2
by: dave | last post by:
Hi, I have searched for the answer for this error message without success. I have seen the question many times though:) I create an ASP.NET project (VS 2005, C#), and use a very simple .mdf...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.