tags:

views:

144

answers:

5

Hi boys:

I was programming an application in C++ Builder 6, and I had encountered this rare problem:

void RotateDice()
{
  Graphics::TBitmap *MYbitmap = new Graphics::TBitmap();

  Randomize();
  int rn = random(6) + 1;

  switch (rn)
  {
    case 1:
    {
        //...
        break; 
    }
    //...  Some cases...
  }

  ShowDice();  //it's a function to show the dice
  delete MYbitmap;   //the compiler don't get it!!!!
}

In the line "ShowDice()", the compiler jumps to the final of the RotateDice() method, it doesn't "see" the line "delete MYbitmap". When I compile the program, every compiled line shows a little blue point in its left side, but that line don't show the blue point... it's like the compiler don't "see" the line of code. What's happening with that????

Note: Some days ago, I was writing a program in Delphi and I was advice of that problematic issue. Some like that happened to me in Delphi 7... So, waht the problem with that?

I am so sorry about my English. I am from Cuba.

+2  A: 

As I understood your problem, when you trace your application, the debugger "jumps over" the line delete MYbitmap;?

  1. Try to put a breakpoint to this line. If it is not marked as such, we have strange IDE bug.

    ShowDice();
    delete MYbitmap;
    int a = 0; // try to add this dummy line and debug again
    
  2. Maybe ShowDice(); throws an exception? Then you'll never reach this line. Try to catch all exceptions and print the result. If it is the case, your code should similar to:

    try {
       ShowDice();
    }
    catch(...) {  // catch all exceptions and do something with them
       delete MYbitmap;
       throw;
    }
    delete MYbitmap;
    
dma_k
In example 2, Mybitmap doesn't get deleted if ShowDice() doesn't throw.
Bill
No, no exceptions is possible in ShowDice();
DelphiProgrammer
Bill, thanks of comment. I have fixed that. Pitty, there is not standard for "finally".MLB: How trick with "int a = 0" behaves? Also skips it?
dma_k
@dma_k There's no "finally" because what you're supposed to do is wrap the MYbitmap pointer in an object that deletes it on destruction.
Tyler McHenry
+2  A: 

Since the ShowDice(); call doesn't depend on the MYbitmap variable, the compiler is free to re-order the last two statements. This might explain why you don't "hit" the line in the debugger. Disable optimization and try again.

Also, may I suggest using some RAII wrapper like std::auto_ptr or boost::scoped_ptr instead of manual memory management?

Nikolai N Fetissov
A: 

You could try:

void RotateDice()
{
  Graphics::TBitmap MYbitmap;
  ...

  ShowDice();
  // No delete needed
};

Creating a TBitmap on the stack means that C++ is forced to delete it properly, even if ShowDice() throws an exception.

Does this work with C++ Builder 6?

quamrana
No, TBitmap is a VCL class (which can't be created on the stack due to Delphi interoperability)
Jon Benedicto
That looks like a declaration of a function named MYbitmap that takes void and returns a TBitmap.
bk1e
@bk1e: Sorry, corrected.
quamrana
+1  A: 

Did you have optimization enabled when you compiled? Optimization has a way of making code that's very confusing to execute under a debugger. Try doing a full recompile with debugging information on and optimization completely disabled, just as a test.

Mark B
A: 

C++ Builder 6 compiler has a bug, rarely showing itself when you use these constructs:

1)

if(condition)
{
    <somecode>
    break;
}

2)

if(condition)
{
    <somecode>
    continue;
}

3)

if(condition)
{
    <somecode>
    goto label;
}

Here, "somecode" is going to be always skipped or always run with no regard to the result of the condition evaluation. The problem is solved when you remove "continue", "break" or "goto". It seems that the switch statement with a break could also have such "feature". Try to change the code before the glitched line this way:

if(rn == 1)
{
        //...
}
   //...  other cases...
else if(rn == ...)
{
   //... 
}
ShowDice();  //it's a function to show the dice
delete MYbitmap;   //works?
Alsk