Can Iterators Trash The Heap?

C

cppaddict

I'm running a Java application that uses a native C++ library I've
written. The Java application hits one of the native methods pretty
frequently (about 100 ms or so), and while it usually works fine,
sometimes the program crashes with an error message about the heap.

The method which seems to be causing the problem is very simple, and
does no manual manipulation of the heap. But it does use an iterator.
Could this be the issue?

Other things to note about the error. The "Function=" part references
a function that is NEVER used in my app. The method referenced by the
current Java thread referenced is used, however.

I've renamed the methods below for clarity. Everything else is cut
and pasted from the error output.

Thanks for any help,
cpp

------------------ERROR MESSAGE FOLLOWS---------------------------

The Java method

Unexpected Signal : EXCEPTION_ACCESS_VIOLATION (0xc0000005) occurred
at PC=0x2C9
0A47
Function=Java_MyClass_methodWhichIsNeverUsedInMyApp+0xA757
Library=C:\myLibrary.dll

Current Java thread:
at MyClass.methodWhichUsesIterator(Native Method)
.......

Heap at VM Abort:
Heap
def new generation total 576K, used 350K [0x10010000, 0x100b0000,
0x104f0000)

eden space 512K, 56% used [0x10010000, 0x10057be0, 0x10090000)
from space 64K, 100% used [0x100a0000, 0x100b0000, 0x100b0000)
to space 64K, 0% used [0x10090000, 0x10090000, 0x100a0000)
tenured generation total 1408K, used 36K [0x104f0000, 0x10650000,
0x14010000)

the space 1408K, 2% used [0x104f0000, 0x104f91b0, 0x104f9200,
0x10650000)
compacting perm gen total 4096K, used 1186K [0x14010000, 0x14410000,
0x1801000
0)
the space 4096K, 28% used [0x14010000, 0x14138bf0, 0x14138c00,
0x14410000)
 
T

tom_usenet

I'm running a Java application that uses a native C++ library I've
written. The Java application hits one of the native methods pretty
frequently (about 100 ms or so), and while it usually works fine,
sometimes the program crashes with an error message about the heap.

The method which seems to be causing the problem is very simple, and
does no manual manipulation of the heap. But it does use an iterator.
Could this be the issue?

If you are using the iterator incorrectly, then yes, of course.
Obviously doing anything at all except assigning to an invalidated
iterator causes undefined behaviour.

Tom
 
C

cppaddict

If you are using the iterator incorrectly, then yes, of course.
Obviously doing anything at all except assigning to an invalidated
iterator causes undefined behaviour.

Sorry, I should have posted the code. Here it is... it test if the
given set of Point - Color values match those at a given position on
the screen:

bool NativeOcr::testPoints(Point positionCoords, std::map<Point,
COLORREF> testPnts) const {

//if one point mismatches, we set it to false and return
bool retVal = true;

std::map<Point, COLORREF>::iterator iter;
int x,y;
for (iter = testPnts.begin(); iter != testPnts.end(); ++iter)
{
Point offset = iter->first;
COLORREF testColor = iter->second;
x = positionCoords.getX() + offset.getX();
y = positionCoords.getY() + offset.getY();
if (GetPixel(hDc_,x,y) != testColor) {
retVal = false;
break;
}
}

return retVal;
}
 
T

tom_usenet

Sorry, I should have posted the code. Here it is... it test if the
given set of Point - Color values match those at a given position on
the screen:

bool NativeOcr::testPoints(Point positionCoords, std::map<Point,
COLORREF> testPnts) const {

Did you mean to pass the map by value? Something like this would be
better:

bool NativeOcr::testPoints(Point positionCoords, std::map<Point,
COLORREF> const& testPnts) const {
//if one point mismatches, we set it to false and return
bool retVal = true;

std::map<Point, COLORREF>::const_iterator iter,
end = testPnts.end();
int x,y;
for (iter = testPnts.begin(); iter != end; ++iter)
{
Point const& offset = iter->first;
COLORREF testColor = iter->second;
x = positionCoords.getX() + offset.getX();
y = positionCoords.getY() + offset.getY();
if (GetPixel(hDc_,x,y) != testColor) {
retVal = false;
break;
}
}

return retVal;
}

In any case, I couldn't see a bug in the original code, apart from the
noted performance bug. This implies that you must be corrupting the
heap or causing undefined behaviour in another function somewhere.

Tom
 
C

cppaddict

In any case, I couldn't see a bug in the original code, apart from the
noted performance bug. This implies that you must be corrupting the
heap or causing undefined behaviour in another function somewhere.

Any idea why the error I posted is saying that there is an access
violation on a function that is NEVER used ANYWHERE in my app. Can
this be caused by heap overflow?

Here's the relevant part of the error message again:

Unexpected Signal : EXCEPTION_ACCESS_VIOLATION (0xc0000005) occurred
at PC=0x2C9
0A47
Function=Java_MyClass_methodWhichIsNeverUsedInMyApp+0xA757

Thanks again,
cpp
 
J

Jerry Coffin

[ ... ]
bool NativeOcr::testPoints(Point positionCoords, std::map<Point,
COLORREF> testPnts) const {

//if one point mismatches, we set it to false and return
bool retVal = true;

std::map<Point, COLORREF>::iterator iter;
int x,y;
for (iter = testPnts.begin(); iter != testPnts.end(); ++iter)
{
Point offset = iter->first;
COLORREF testColor = iter->second;
x = positionCoords.getX() + offset.getX();
y = positionCoords.getY() + offset.getY();
if (GetPixel(hDc_,x,y) != testColor) {
retVal = false;
break;
}
}

return retVal;
}

I don't see an obvious bug in this code -- I suspect you're looking in
the wrong place. OTOH, I'd personally write the code a bit
differently, something along these lines:

// warning: untested code.
typedef std::pair<Point, COLORREF> mapped;

struct pt_mm : public std::binary_function<Point, mapped, bool> {
bool operator()(Point const &pos, mapped const &i) const {
HDC hDc_;
Point offset = i.first;

int x = pos.getX() + offset.getX();
int y = pos.getY() + offset.getY();
return GetPixel(hDc_, x, y) != i.second;
}
};

typedef std::map<Point, COLORREF> ptmap;

bool NativeOcr::testPoints(Point const &pos, ptmap const &pts) {
return std::find_if(pts.begin(), pts.end(),
std::bind1st(pt_mm(), pos)) == pts.end();
}

As a less topical aside, if your call to GetPixel is to the one in
Windows, you might want to check in a Windows programming newsgroup
about how to use a DIBSection instead -- it'll probably be quite a bit
faster.
 
C

cppaddict

As a less topical aside, if your call to GetPixel is to the one in
Windows, you might want to check in a Windows programming newsgroup
about how to use a DIBSection instead -- it'll probably be quite a bit
faster.

Jerry,

You have a sharp eye. After many hours bug tracking yesterday, I
traced almost all problems in my app (both bugs and speed) to
excessive use of GetPixel. It is:

1. Not thread safe. Having multiple threads access it causes strange
heap and memory exception errors.

2. Slow. I am looking for an alternative now. I'll take a look at
DIBSECTION. I was also thinking of of BitBlt

Let me know if you have any other advice.

Thanks again,
cpp
 
O

Old Wolf

cppaddict said:
I traced almost all problems in my app (both bugs and speed) to
excessive use of GetPixel. It is:

1. Not thread safe. Having multiple threads access it causes strange
heap and memory exception errors.

You should assume things are not thread-safe, unless there is
specific documentation to the contrary. In particular, any Windows
objects (eg. windows, GDI objects, strings, timers, ...) are most
unlikely to be thread-safe, you should either use mutexes, or only
access them from one thread.
2. Slow. I am looking for an alternative now. I'll take a look at
DIBSECTION. I was also thinking of of BitBlt

GetPixel was designed for occasional use.. if you need to scan a
large area you should retrieve that area to memory first and then
work within that memory. IMHO the windows GDI interface is horrible,
I'd suggest you use some other graphics library for manipulating
images and then blit them to the screen when appropriate.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top