• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 323
  • Last Modified:

deleting object instance

hi,

I have the sort of code snippet below and am curious something about it.
As obviously seen, i am creating a new window object instance and immediately
deleting it, but it's still possible to call the member functions of the object.


void CMenusDlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
     CDialog w;
     delete w;
     w.Create( .. );
     w.FlashWindow( TRUE );
        ...

        ...
}


what the heck is this?. i think that instance creation in the local scope
makes the object permanent although the delete operator used. is it safe to use like
this way? i'm confused a little, what do you comment on it?


Thanks in advance.
Osman Mavideniz
0
omavideniz
Asked:
omavideniz
  • 10
  • 7
  • 2
  • +3
1 Solution
 
jtm111Commented:
Stroustrup notes that in the C++ standard, access to an object after it has been deleted is undefined.

It doesn't surprise me that you could run instructions after deleting an object. But it is absolutely bad practice. Your code is not portable because you don't know how C++ compilers will handle your code.

Never use an object after you delete it.
0
 
omavidenizAuthor Commented:
hi jtm111,

my problem is not about using an object after deleting it, i don't want to make use of it. but the concept of local instance creation and destruction, that if you create a dynamic object instead;

CDialog w = new CDialog();
delete w;    

method calls now crash, because of the obvious destruction of the object but why not the same thing applies the previous one...
0
 
jtm111Commented:
Oh I see... You aren't creating the object with new. I was focusing on the delete line.

In the C++ standard, delete only has an effect for a pointer returned by new or to 0 which has no effect (Stroustrup, p. 128).

I would expect a compiler warning or error if you try to delete anything other than a pointer or 0. Didn't you get one?

If not, I suspect it simply ignored the delete operator, in which case your program would run.

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
nietodCommented:
>> I would expect a compiler warning or
>> error if you try to delete anything
>> other than a pointer or 0.
So would I!!

That code absolutely should not compile.  
0
 
omavidenizAuthor Commented:
that code definitely compiles within VC++ 6.0 and no errors or warnings raised.
0
 
omavidenizAuthor Commented:
that code definitely compiles within VC++ 6.0 and no errors or warnings raised.
0
 
nietodCommented:
The code definitely does not compile in vc 6.0.  I tried it.

Are you sure you are compiling this code?  perhaps the file you have is not included in the project.  Place a blantent error in the code (although you really have) and see what happens, like

  CDialog w;
  delete w;
  this line surely is a compiler error;
0
 
jhanceCommented:
>>this line surely is a compiler error;

You would think so but it's not flagged as an error in VC++ 6.0!!  Try it....

0
 
omavidenizAuthor Commented:
as jhance stated its neither an error nor warning in VC++ 6.0.
0
 
nietodCommented:
Huh?  I did try it.  I got two errors.  c2059 and c2238

This makes no sense?
0
 
omavidenizAuthor Commented:
actually, i'm curious about how vc++ handles to prevent the delete to destroy the local object. is it using some smart technique to determine the local objects and prevent their destruction, or the c++ language concept provides this mechanism implicitly to prohibit the local object destruction.
0
 
nietodCommented:
Are you sure you guys are compiling this.  It is clearly a syntax error.  It is one that VC reports for all cases I can construct (any non-pointer) as well as this specific case

the only think I can think if is that an implicit conversion to some pointer type is being called on the object.  But the object doesn't define any pointer conversions that I am aware of, and even if it does, no conversion should be invoked by the compiler in this case.  So that hardly seeems like that is what is happening, but it the only think I can think of.  (And it doesn't work for me!)
0
 
jhanceCommented:
>>This makes no sense?

Agreed!  I'm 100% positive that I'm compiling it.  And I get no errors or warnings at all on it.  I even bumped the C++ warning level up to 4 and nothing.

Could this be a VC++ version issue?  Like some rev levels have a problem with this and others don't?  I think I have VC++ SP3 installed but I'm not sure about it..  It might be a later one.
0
 
omavidenizAuthor Commented:
the explanation of the errors you reported are below and makes no sense of our subject. may be some of our compiler settings causes the difference, i'm not sure why we are encountering different compiler behaviours.

----------
Compiler Error C2059
syntax error : 'token'

The token caused a syntax error. Problems of this type can sometimes be attributed to a syntactical or clerical error. For example:

void main (             // No closing parenthesis.
{

}

----------
Compiler Error C2238
unexpected token(s) preceding 'token'

An incorrect token, or tokens, was found before the specified token.

This error can be caused by an invalid name in a bit-field declaration.

The following is an example of this error:

struct bits
{
   int field1 : 16;
   int 9      : 16;  // error, 9 is not a valid name
};


0
 
nietodCommented:
>> actually, i'm curious about how vc++
>> handles to prevent the delete to destroy
>> the local object. is it
>> using some smart technique to determine
>> the local objects and prevent their
>> destruction,
Nope.  delete on an non-pointer type is a syntax error.  it does not matter where it comes from (local or heap).   Delete on a pointer is never a syntax error.  Now if the pointer was not allocated with new, then the delete operation is a semantic error, but not a syntax error and the compiler will not complain about it, but the program behavior is undefined--and rarely good!

So for example

int *iptr = new int;

delete *iptr; // syntax error.  does not compile.  this
         // int is from the heap, but you cannot delete
         // an int, only a pointer.  


int i - 5;
delete &i; // This compiles.  But the behavior
    // is undefined.  Probably causes a crash.

>> Could this be a VC++ version issue?
Its possible, but seems unlikely.  Though nothing else seems more likely.

Can you guts try this other other data types?  What does

int i;
delete i;

do?
0
 
nietodCommented:
>> explanation of the errors you reported
>> are below and makes no sense of our subject
yes they do.  The first is the error I would expect.  The 2nd is a sideffect of it trying to continue after the first error.  
0
 
omavidenizAuthor Commented:
i tried it for int and get the error,

Compiler Error C2541
delete : cannot delete objects that are not pointers

may be cause of a vc++ issue it doesn't expose the same error for user-defined objects.

0
 
nietodCommented:
Strange that I don't get C2541 when I do get an error for the class then.   I need to do a bit of research here...
0
 
nietodCommented:
Now this must be a version issue.  When I do
 int i;
 delete i;

I get the same erros as when I try to delete the object, that is, I get C2059 and C2238 in both cases.

I can't do the next test though.

Can you step into the delete of this object in the debugger.  Look to see if a conversion operator for the CDialog class is being called.  I am 99.9% sure that is not allowed, but it mgiht be a mistake in the VC compiler that then allows this code to compile.
0
 
jasonclarkeCommented:
CDialog (from CWnd) defines operator HWND, which is a void* (I think - sometimes, can be a struct if STRICT is defined?, in which case it won't compile?), hence this compiles, as an example, this also compiles:

class X
{
public:
    operator void*()
    {
        return 0;
    }
};

int main()
{
    X theX;
    delete theX;
}

0
 
nietodCommented:
So it is a conversion?   I didn't think that was allowed.  I have to look into that I'm not sure what the rules are for that.   Like if a class has two pointer conversions, which one would delete use, or would then be ambiguous.
0
 
nietodCommented:
Okay for delete you are allowed one conversion to a pointer in a  class.  The standard says

*********************************

1 The  delete-expression  operator  destroys  a  most   derived   object
  (_intro.object_) or array created by a new-expression.
          delete-expression:
                  ::opt delete cast-expression
                  ::opt delete [ ] cast-expression
  The  first alternative is for non-array objects, and the second is for
  arrays.  The operand shall have a pointer type, or a class type having
  a  single  conversion  function  (_class.conv.fct_) to a pointer type.

***********************************8
so you are allowed to call delete on an object if its class defines a single conversion function to a pointer.  CDialog provides a conversion to an HWND.  If STRICT is not defined this is a pointer, and so the code will compiler.

But how what happens in this case?  Well delete does not delete the CDialog you specify.  (which woudl be a bad thing.)  The CDialog conversion function returns a window handle.   If the dialog is closed this handle is NULL, so the delete is performed on a NULL pointer, which does nothing, and thuse the code is fine.  In this case the CDialog is not deleted and nothing else is deleted.  No harm is done.  But if the dialog is open, the the covnersion returns a non-NULL pointer.  Delete will execute on this pointer.  But this is not a pointer to an object allocated fromt he C++ heap and thus this will cause unpredictable behavior.   This is bad.
0
 
amp072397Commented:
omavideniz:

You have many open questions:

http://www.experts-exchange.com/jsp/qShow.jsp?qid=20222327
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20261522
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20255833
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20248161
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20247596
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20247451
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20239442
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20235419
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20234355
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20230738
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20227630
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20210091
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20163508
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20163400
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20156064
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20151257
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20149551
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20107807
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20107283
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20096836
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20095000
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20094242
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20081432
http://www.experts-exchange.com/jsp/qShow.jsp?qid=20068029
http://www.experts-exchange.com/jsp/qShow.jsp?qid=12040399
http://www.experts-exchange.com/jsp/qShow.jsp?qid=12040320

To assist you in your cleanup, I'm providing the following guidelines:

1.  Stay active in your questions and provide feedback whenever possible. Likewise, when feedback has not been provided by the experts, commenting again makes them receive an email notification, and they may provide you with further information. Experts have no other method of searching for questions in which they have commented, except manually.

2.  Award points by hitting the Accept Comment As Answer button located above and to the left of that expert's comment.

3.  When grading, be sure to read:
http://www.experts-exchange.com/jsp/cmtyQuestAnswer.jsp#3
to ensure that you understand the grading system here at EE. If you grade less than an A, you must explain why.

4.  Questions that were not helpful to you should be PAQ'd (stored in the database for their valuable content?even if not valuable to you) or deleted. To PAQ or delete a question, you must first post your intent in that question to make the experts aware. Then, if no experts object after three full days, you can post a zero-point question at community support to request deletion or PAQ. Please include the link(s) to the question(s).
CS:  http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
At that point, a moderator can refund your points and PAQ or delete the question for you. The delete button does not work.

5.  If you fail to respond to this cleanup request, I must report you to the Community Support Administrator for further action.

Our intent is to get the questions cleaned up, and not to embarrass or shame anyone. If you have any questions or need further assistance at all, feel free to ask me in this question or post a zero-point question at CS. We are very happy to help you in this task!


thanks!
amp
community support moderator

2/6
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 10
  • 7
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now