Another debugger question

J

JoeC

What does this mean and how can I use it to track down a bug?

*void operator delete() - delete a block in the debug heap
*
*Purpose:
* Deletes any type of block.
*
*Entry:
* void *pUserData - pointer to a (user portion) of memory block
in the
* debug heap
*
*Return:
* <void>
*

*dbgnew.cpp - defines C++ scalar delete routine, debug version

void operator delete(
void *pUserData
)
{
_CrtMemBlockHeader * pHead;

RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

if (pUserData == NULL)
return;

_mlock(_HEAP_LOCK); /* block other threads */
__TRY

/* get a pointer to memory block header */
pHead = pHdr(pUserData);

/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

_free_dbg( pUserData, pHead->nBlockUse );

__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY

return;
}

#endif /* _DEBUG */
 
J

JoeC

The below is the operator delete function. If one if its asserts is
firing, probably either you are trying to delete something that wasn't
newed, or you are trying to delete something twice.

Thanks, I figured that out when I commented out the delete. I am
trying to learn how to use the debugger. I don't delete the array any
where but in the delete. I am wondering if the program is doing
something where it is messing with my array when it runs. I only read
data and change the values of the array elements.

I did get this in my array pointer with the debugger:
BYTE * bits; CXX0034: Error: types incompatible with operator

I don't know where my array can be deleted. I create the array in the
constructor then I modify colors then I display the graphic.

Constructor:

bits = new BYTE[acc*dwn];

for(int lp =0; lp != (acc*dwn); lp++)
bits[lp]=0;

Then I set the colors to 0:

for(int lp =0; lp != 16; lp++){
bInfo.bmiColors[lp].rgbBlue = 0;
bInfo.bmiColors[lp].rgbGreen = 0;
bInfo.bmiColors[lp].rgbRed = 0;
bInfo.bmiColors[lp].rgbReserved = 0;
}

colors[1].setColor(255,0,255);
colors[2].setColor(0,255,255);
colors[3].setColor(255,255,0);

for(int lp = 0; lp != 3; lp++){

b.setColor(lp,colors[lp].r(),colors[lp].g(),colors[lp].b());
}

Code:

void bitmap::setColor(int n, BYTE r, BYTE g, BYTE b){

bInfo.bmiColors[n].rgbBlue = b;
bInfo.bmiColors[n].rgbGreen = g;
bInfo.bmiColors[n].rgbRed = r;
bInfo.bmiColors[n].rgbReserved = 0;


}

The only other thing I can think of is that I declare the bitmap in
main:

bitmap b;

then I access them as globals and externs:
extern bitmap b;
 
J

JoeC

JoeC said:
Thanks, I figured that out when I commented out the delete.  I am
trying to learn how to use the debugger.  I don't delete the array any
where but in the delete.  I am wondering if the program is doing
something where it is messing with my array when it runs.  I only read
data and change the values of the array elements.
I did get this in my array pointer with the debugger:
    BYTE * bits;   CXX0034: Error: types incompatible with operator
I don't know where my array can be deleted.  I create the array in the
constructor then I modify colors then I display the graphic.

You should be able to delete the array in the destructor. Remember to
use the array form of delete.

It is also possible that you are scribbling on the memory from somewhere
else. One way to check this would be to do something like:

(assuming BYTE is a pseudonym for an 8 bit, unsigned char)

bits = new BYTE[acc*dwn + 16];
memset(bits, 0xFD, acc*dwn + 16];
bits += 8;

Then just before you delete the memory do this:

bits -= 8;
for (int i = 0; i < 8; ++i)
   assert(bits == 0xFD);
for (int i = acc*dwn + 8; i < acc*dwn + 16; ++i)
   assert(bits == 0xFD);

If either of these asserts fire, then you are writing outside your
allocated memory.


Thanks, Ill try that and get back to and let you know how it worked.
I would never have thought about that.
 
J

JoeC

JoeC said:
Thanks, I figured that out when I commented out the delete.  I am
trying to learn how to use the debugger.  I don't delete the array any
where but in the delete.  I am wondering if the program is doing
something where it is messing with my array when it runs.  I only read
data and change the values of the array elements.
I did get this in my array pointer with the debugger:
    BYTE * bits;   CXX0034: Error: types incompatible with operator
I don't know where my array can be deleted.  I create the array in the
constructor then I modify colors then I display the graphic.

You should be able to delete the array in the destructor. Remember to
use the array form of delete.

It is also possible that you are scribbling on the memory from somewhere
else. One way to check this would be to do something like:

(assuming BYTE is a pseudonym for an 8 bit, unsigned char)

bits = new BYTE[acc*dwn + 16];
memset(bits, 0xFD, acc*dwn + 16];
bits += 8;

Then just before you delete the memory do this:

bits -= 8;
for (int i = 0; i < 8; ++i)
   assert(bits == 0xFD);
for (int i = acc*dwn + 8; i < acc*dwn + 16; ++i)
   assert(bits == 0xFD);

If either of these asserts fire, then you are writing outside your
allocated memory.


Yes
assert(bits == 0xFD);
threw an exemption what I ran the program under debug. What could be
causing that?

Other than this code I am only reading and modifying the elements of
the array. Later I will expand the array as I want to add more
graphics.

I am trying to do a color bitmap of this program:

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=11996&lngWId=3
 
J

JoeC

 JoeC said:
Thanks, I figured that out when I commented out the delete.  I am
trying to learn how to use the debugger.  I don't delete the array any
where but in the delete.  I am wondering if the program is doing
something where it is messing with my array when it runs.  I only read
data and change the values of the array elements.
I did get this in my array pointer with the debugger:
    BYTE * bits;   CXX0034: Error: types incompatible with operator
I don't know where my array can be deleted.  I create the array in the
constructor then I modify colors then I display the graphic.
You should be able to delete the array in the destructor. Remember to
use the array form of delete.
It is also possible that you are scribbling on the memory from somewhere
else. One way to check this would be to do something like:
(assuming BYTE is a pseudonym for an 8 bit, unsigned char)
bits = new BYTE[acc*dwn + 16];
memset(bits, 0xFD, acc*dwn + 16];
bits += 8;
Then just before you delete the memory do this:
bits -= 8;
for (int i = 0; i < 8; ++i)
   assert(bits == 0xFD);
for (int i = acc*dwn + 8; i < acc*dwn + 16; ++i)
   assert(bits == 0xFD);
If either of these asserts fire, then you are writing outside your
allocated memory.

Yes
   assert(bits == 0xFD);
threw an exemption what I ran the program under debug.  What could be
causing that?


Which assert fired, the one that checks the first 8 bites or the one
that checks the last 8 bites? If the later, then your problem is likely
that you aren't allocating enough memory.

Is there any chance you could work at a higher level than BYTEs? Or at
least work with vectors? Otherwise you are going to be having all kinds
of hard to track down bugs.


I did try to allocate many times what I would need for memory and it
still crashed. I would rather use an int but BYTE is what the type
that the bitmap command has for input type.Ill try a vector see it
will work.
 
J

JoeC

 JoeC said:
Thanks, I figured that out when I commented out the delete.  I am
trying to learn how to use the debugger.  I don't delete the array any
where but in the delete.  I am wondering if the program is doing
something where it is messing with my array when it runs.  I only read
data and change the values of the array elements.
I did get this in my array pointer with the debugger:
    BYTE * bits;   CXX0034: Error: types incompatible with operator
I don't know where my array can be deleted.  I create the array in the
constructor then I modify colors then I display the graphic.
You should be able to delete the array in the destructor. Remember to
use the array form of delete.
It is also possible that you are scribbling on the memory from somewhere
else. One way to check this would be to do something like:
(assuming BYTE is a pseudonym for an 8 bit, unsigned char)
bits = new BYTE[acc*dwn + 16];
memset(bits, 0xFD, acc*dwn + 16];
bits += 8;
Then just before you delete the memory do this:
bits -= 8;
for (int i = 0; i < 8; ++i)
   assert(bits == 0xFD);
for (int i = acc*dwn + 8; i < acc*dwn + 16; ++i)
   assert(bits == 0xFD);
If either of these asserts fire, then you are writing outside your
allocated memory.

Yes
   assert(bits == 0xFD);
threw an exemption what I ran the program under debug.  What could be
causing that?


Which assert fired, the one that checks the first 8 bites or the one
that checks the last 8 bites? If the later, then your problem is likely
that you aren't allocating enough memory.

Is there any chance you could work at a higher level than BYTEs? Or at
least work with vectors? Otherwise you are going to be having all kinds
of hard to track down bugs.


I did some work on this it seems there is something strange going on.
I create the array and it is OK but after a few lines of code the
memory gets corrupted.

bits = new BYTE[acc*dwn];

if(bits == NULL){MessageBox(NULL, "HELP 2", "Info", MB_OK);} <-
does not trigger

for(int lp =0; lp > (acc*dwn); lp++){
bits[lp]=0;
}

//create();
bInfo.bmiHeader.biHeight = dwn;
bInfo.bmiHeader.biWidth = acc;
bInfo.bmiHeader.biClrUsed = 16;



for(int lp =0; lp != 16; lp++){
bInfo.bmiColors[lp].rgbBlue = 0;
bInfo.bmiColors[lp].rgbGreen = 0;
bInfo.bmiColors[lp].rgbRed = 0;
bInfo.bmiColors[lp].rgbReserved = 0;
}

if(bits == NULL){MessageBox(NULL, "HELP 3", "Info", MB_OK);} <-
this does trigger.

The first bit == null does not trigger a box but in a few lines the
memory get corrupted or cleared and the help three show that there is
some corruption because this is all in the same function and the array
is not modified or accessed but the memory seem to be automatically
set to NULL.
 
J

JoeC

JoeC said:
I did some work on this it seems there is something strange going on.
I create the array and it is OK but after a few lines of code the
memory gets corrupted.
 bits = new BYTE[acc*dwn];
    if(bits == NULL){MessageBox(NULL, "HELP 2", "Info", MB_OK);} <-
does not trigger
    for(int lp =0; lp > (acc*dwn); lp++){
          bits[lp]=0;
    }
 //create();
 bInfo.bmiHeader.biHeight = dwn;
    bInfo.bmiHeader.biWidth = acc;
    bInfo.bmiHeader.biClrUsed = 16;
   for(int lp =0; lp != 16; lp++){
       bInfo.bmiColors[lp].rgbBlue = 0;
       bInfo.bmiColors[lp].rgbGreen = 0;
       bInfo.bmiColors[lp].rgbRed = 0;
       bInfo.bmiColors[lp].rgbReserved = 0;
     }
   if(bits == NULL){MessageBox(NULL, "HELP 3", "Info", MB_OK);} <-
this does trigger.
The first bit == null does not trigger a box but in a few lines the
memory get corrupted or cleared and the help three show that there is
some corruption because this is all in the same function and the array
is not modified or accessed but the memory seem to be automatically
set to NULL.

If the code above is all in the same function then the last loop in your
code is writing over the 'bits' variable. You are going to have to go
through all of your code and make sure that you are not dereferencing
invalid pointers. Has bmiColors been allocated to hold enough memory?
Check every pointer/array that is accessed between the first messagebox
call and the second one; one of them is accessing invalid memory.

FYI, this is one of the hardest types of bugs to track down.

Thanks for the help. This is getting fustrating and I did comment it
out and it seemed to work. I can I be sure that I don't conflict
memory?

I have no idea if bmiColors has enough memory is is part of:
BITMAPINFO bInfo;

That is a windows function and I used this:

ZeroMemory(&bInfo.bmiHeader, sizeof(BITMAPINFOHEADER) );
bInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 
J

Jonathan Lee

   for(int lp =0; lp != 16; lp++){
        bInfo.bmiColors[lp].rgbBlue = 0;
        bInfo.bmiColors[lp].rgbGreen = 0;
        bInfo.bmiColors[lp].rgbRed = 0;
        bInfo.bmiColors[lp].rgbReserved = 0;
     }

My guess is that bmiColors is not as big as you think it is.

It's just a dummy field at the end of a struct, only declared
to have one element. Look at MS's documentation. It's
something like

RGBQUAD bmiColors[1];

--Jonathan
 
J

JoeC

   for(int lp =0; lp != 16; lp++){
        bInfo.bmiColors[lp].rgbBlue = 0;
        bInfo.bmiColors[lp].rgbGreen = 0;
        bInfo.bmiColors[lp].rgbRed = 0;
        bInfo.bmiColors[lp].rgbReserved = 0;
     }

My guess is that bmiColors is not as big as you think it is.

It's just a dummy field at the end of a struct, only declared
to have one element. Look at MS's documentation. It's
something like

  RGBQUAD bmiColors[1];

--Jonathan

Thanks all for the help. I have to use some structures to make the
graphic but yet those structures are out of my control. Any
suggestion on commands or where I can look to try to take control of
BITMAPINFO and make sure that here is enough memory allocated for
colors. I can get may program to run reasonably well if I take out
some commands. I did go through a long process to find which commands
and structures to use to get this program to work.
 
J

Jonathan Lee

Thanks all for the help.  I have to use some structures to make the
graphic but yet those structures are out of my control.

In this particular case, the struct is designed for C rather than
C++. The usage isn't regular in C, but it's not *that* unusual.
Basically, every once in a while you have a chunk of data that
has a header, and then some variable length array after it. Such
as BITMAPINFO. The idea is that you malloc() enough memory for
the header _and_ the data, then cast the pointer to BITMAPINFO*.
This way you can index into bmiColors without running over the
end of the data, even though you're running over the end of the
struct.

I wouldn't say it's out of your control, just that this is an
unexpected way of doing things from a C++ perspective. Which
is good in a way; there are better ways to handle this in C++.
Any suggestion on commands or where I can look to try to
take control of BITMAPINFO and make sure that here is enough
memory allocated for colors.

I presume you're writing some kind of Bitmap class? It could
be as simple as doing the above: alloc the right amount of
memory, cast to BITMAPINFO*, use the pointer, free it.
Something like

BITMAPINFO* get_bitmapinfo_ptr(size_t number_of_bmicolors);
void free_bitmapinfo_ptr(BITMAPINFO*);

But really, why deal with BITMAPINFO at all? Just store the
colors separately, in a vector of RGBQUAD-s. The only thing
inside BITMAPINFO is a BITMAPINFOHEADER and the array. It's
kindofa useless structure.

So split the structure into two data members of your Bitmap
class. By and large this will be a find-and-replace kind of
change to your source. The only problem, I expect, would be
if you are reading a file. It's possible you were reading a
whole file in one step, rather than reading the header to
one struc and the pixel data to another. But that's not to
change.

--Jonathan
 
J

JoeC

In this particular case, the struct is designed for C rather than
C++. The usage isn't regular in C, but it's not *that* unusual.
Basically, every once in a while you have a chunk of data that
has a header, and then some variable length array after it. Such
as BITMAPINFO. The idea is that you malloc() enough memory for
the header _and_ the data, then cast the pointer to BITMAPINFO*.
This way you can index into bmiColors without running over the
end of the data, even though you're running over the end of the
struct.

I wouldn't say it's out of your control, just that this is an
unexpected way of doing things from a C++ perspective. Which
is good in a way; there are better ways to handle this in C++.


I presume you're writing some kind of Bitmap class? It could
be as simple as doing the above: alloc the right amount of
memory, cast to BITMAPINFO*, use the pointer, free it.
Something like

  BITMAPINFO* get_bitmapinfo_ptr(size_t number_of_bmicolors);
  void free_bitmapinfo_ptr(BITMAPINFO*);

But really, why deal with BITMAPINFO at all? Just store the
colors separately, in a vector of RGBQUAD-s. The only thing
inside BITMAPINFO is a BITMAPINFOHEADER and the array. It's
kindofa useless structure.

So split the structure into two data members of your Bitmap
class. By and large this will be a find-and-replace kind of
change to your source. The only problem, I expect, would be
if you are reading a file. It's possible you were reading a
whole file in one step, rather than reading the header to
one struc and the pixel data to another. But that's not to
change.

--Jonathan

Thanks for all the suggestions:

It was a challenge understanding how to do the bitmap and I have to
use the following commands and methods for creating the graphic:

VOID *pvBits;

HBITMAP hbitmap = CreateDIBSection(dc,&bInfo,
DIB_RGB_COLORS,
&pvBits,NULL,0 );


CopyMemory(pvBits, bits, (acc*dwn));

I will take some of the suggestions and see if I can get them to
work.
 
J

JoeC

In this particular case, the struct is designed for C rather than
C++. The usage isn't regular in C, but it's not *that* unusual.
Basically, every once in a while you have a chunk of data that
has a header, and then some variable length array after it. Such
as BITMAPINFO. The idea is that you malloc() enough memory for
the header _and_ the data, then cast the pointer to BITMAPINFO*.
This way you can index into bmiColors without running over the
end of the data, even though you're running over the end of the
struct.

I wouldn't say it's out of your control, just that this is an
unexpected way of doing things from a C++ perspective. Which
is good in a way; there are better ways to handle this in C++.


I presume you're writing some kind of Bitmap class? It could
be as simple as doing the above: alloc the right amount of
memory, cast to BITMAPINFO*, use the pointer, free it.
Something like

  BITMAPINFO* get_bitmapinfo_ptr(size_t number_of_bmicolors);
  void free_bitmapinfo_ptr(BITMAPINFO*);

But really, why deal with BITMAPINFO at all? Just store the
colors separately, in a vector of RGBQUAD-s. The only thing
inside BITMAPINFO is a BITMAPINFOHEADER and the array. It's
kindofa useless structure.

So split the structure into two data members of your Bitmap
class. By and large this will be a find-and-replace kind of
change to your source. The only problem, I expect, would be
if you are reading a file. It's possible you were reading a
whole file in one step, rather than reading the header to
one struc and the pixel data to another. But that's not to
change.

--Jonathan

THANKS!!!

I did figure it out. I did some research. I had to create this:

struct BitMap_256{

BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
};

Then I used this:

pBInfo = (BITMAPINFO*) (new BitMap_256);
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top