Access violation reading location *address*
<p><img src="http://i.stack.imgur.com/ab54O.png" alt="enter image description here"></p>

<p><strong>Note(update):</strong> No need to read this entire wall of text.. problem + solution further below.</p>

<p>I would like to, once and for all, find out why I am running into these errors all of the time when creating multithreaded applications. I'm cutting a lot of code out to keep it simple so it won't work if you try to compile it.</p>

<p>This is a queueing system. Entities will be put in groups of 5. 
If, by example, an Entity leaves group 3, group 3 will snatch an entity from another group that has less priority and is not full yet.</p>

<p>All I'm doing at the moment is create entities and queue them, which happens on the main thread. After that, I start a boost thread that will remove 20 entities. This is where the read access violation occurs and I can't figure out what's causing it. How do you debug something like this?</p>

<p><strong>main.h</strong></p>

<pre><code>//Externs, so all files can access the objects. Created in main.cpp .

#include "queue.h"
typedef std::map&lt;unsigned int, Entity*&gt; entityMap; //id,entity
extern entityMap entitymap;
typedef std::map&lt;unsigned int, unsigned int&gt; entityPositionMap; //Position,entityID
extern entityPositionMap entitypositionmap;
extern LFDGroups lfdgroups;
extern Queue queue;
</code></pre>

<p><strong>main.cpp</strong></p>

<pre><code>typedef std::map&lt;unsigned int, Entity*&gt; entityMap;
entityMap entitymap;
typedef std::map&lt;unsigned int, unsigned int&gt; entityPositionMap; //Position,id
entityPositionMap entitypositionmap;
LFDGroups lfdgroups;
Queue queue;

struct threadStarter2
{void operator()(){
    for(unsigned int i = 0;i&lt;20;i++) queue.removeFakeEntity();
}};

int main()
{
    threadStarter1 startit1;
    boost::thread thrd1(startit1);

    whatNext(); //Prevent program exit

    return 0;
}
</code></pre>

<p><strong>queue.cpp</strong></p>

<pre><code>#include "main.h"
#include "queue.h"

Queue::Queue() //Lets add some entities and queue them at application start
{
    for(unsigned int i = 0;i&lt;20;i++){ addFakeEntity(false); }

    //Queue all entities
    std::map&lt;unsigned int, Entity*&gt;::iterator p;
    for(p = entitymap.begin(); p != entitymap.end(); p++) 
    {
        boost::mutex::scoped_lock lock(lfdgroups.access_groupsLookingForMore);
        lfdgroups.addMember(p-&gt;second-&gt;id);
        lock.unlock();
    }
}

void Queue::addFakeEntity(bool queuenow)
{

    Entity *entity = new Entity; 
    entity-&gt;id = entitymap.size();
    entity-&gt;LFDGroupID = NULL;
    entity-&gt;LFD = false;
    entitymap.insert(std::pair&lt;unsigned int,Entity*&gt;(entity-&gt;id,entity)); 

    if(queuenow)
    {
        entity-&gt;LFD = true;
        boost::mutex::scoped_lock lock(lfdgroups.access_groupsLookingForMore);
        lfdgroups.addMember(entity-&gt;id);
        lock.unlock();
    }
}

void Queue::removeFakeEntity()
{
    //Remove random entity from random group
    unsigned int groupID = getrand(0,lfdgroups.groupHeap.size()-1);
    boost::mutex::scoped_lock lock(lfdgroups.access_groupsLookingForMore); //Thread safety
    lfdgroups.groupHeap[groupID]-&gt;removeMember(lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs[getrand(0,lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs.size()-1)],true);
    lock.unlock();
}
</code></pre>

<p>So as you can see, the main thread isn't doing anything at the moment and the boost thread is removing entities one by one.</p>

<p>Here's what actually happens when an entitity is removed (<code>lfdgroups.groupHeap[groupID]-&gt;removeMember()</code>)</p>

<pre><code>bool groupObject::removeMember(unsigned int entityID,bool snatchIt)
{
    boost::mutex::scoped_lock lock(access_group);
    for (unsigned int i = 0;i&lt;arrayOfEntityIDs.size();i++)
    {
        if(arrayOfEntityIDs[i] == entityID) //Messy way of selecting the entity we are looking for.
        {
            std::stringstream ss; 
            ss.str(""); ss.clear(); ss &lt;&lt; "Removed member " &lt;&lt; entityID &lt;&lt; " from group " &lt;&lt; id &lt;&lt; " which has " &lt;&lt; groupSize() - 1 &lt;&lt; " members left." &lt;&lt; std::endl;
            echo(ss.str());
            arrayOfEntityIDs.erase(arrayOfEntityIDs.begin() + i);
            if(snatchIt){ std::cout &lt;&lt; "We have to snatch" &lt;&lt; std::endl; snatch();}
            else{ std::cout &lt;&lt; "We don't have to snatch" &lt;&lt; std::endl;}
            return true;
        }
    }
    lock.unlock();
    return true;
}
</code></pre>

<p>snatchit is set to true, so;</p>

<pre><code>void groupObject::snatch()
{
    boost::mutex::scoped_lock lock(snatching);

    groupObject* thisgroup = NULL;
    thisgroup = this;
    if(!thisgroup) return;

    std::cout &lt;&lt; thisgroup-&gt;id &lt;&lt; " need snatch? " &lt;&lt; thisgroup-&gt;snatchCriteria() &lt;&lt; std::endl;
    if(!thisgroup-&gt;snatchCriteria()) return; //Do we even need to snatch a player (group &lt; 5?) //This is a little redundant atm

    std::map&lt;unsigned int, unsigned int&gt;::iterator p2;
    for(p2 = entitypositionmap.begin(); p2 != entitypositionmap.end(); p2++) 
    {
        Entity* entity = thisgroup-&gt;getEntity(p2-&gt;second);
        if(entity != NULL &amp;&amp; entity-&gt;LFDGroupID != thisgroup-&gt;id)
        {
            groupObject* targetgroup = NULL;
            targetgroup = lfdgroups.getGroupObject(entity-&gt;LFDGroupID);
            if(targetgroup != NULL &amp;&amp; targetgroup-&gt;migrateCriteria())
            {
                lfdgroups.getGroupObject(thisgroup-&gt;id)-&gt;addMember(entity-&gt;id,false);

                std::stringstream ss; 
                ss.str(""); ss.clear(); ss &lt;&lt; "Snatched " &lt;&lt; entity-&gt;id &lt;&lt; " from " &lt;&lt; targetgroup-&gt;id &lt;&lt; " for: " &lt;&lt; thisgroup-&gt;id &lt;&lt; std::endl;
                echo(ss.str());
                break;
            }
        }
    }
    lock.unlock();
}
</code></pre>

<p>What just happened was that the group went over all the entities in the queue until it found one elegible to snatch. After which <code>lfdgroups.getGroupObject(thisgroup-&gt;id)-&gt;addMember(entity-&gt;id,false);</code> takes place (so addmemeber in the group object, not to be confused with lfdgroups' addmember).</p>

<pre><code>bool groupObject::addMember(unsigned int entityID,bool snatchIt)
{
    Entity* entity = getEntity(entityID);
    if(entity == NULL) return false;

    groupObject* group = lfdgroups.getGroupObject(entity-&gt;LFDGroupID);

    if(group != NULL){ if(!group-&gt;removeMember(entityID,snatchIt)){return false;} }

    if(elegibleCheck(entityID))
    {
        arrayOfEntityIDs.push_back(entityID);
        entity-&gt;LFDGroupID = id;

        std::stringstream ss; 
        ss.str(""); ss.clear(); ss &lt;&lt; "Added member " &lt;&lt; entityID &lt;&lt; " to group " &lt;&lt; id &lt;&lt; " which has " &lt;&lt; groupSize() &lt;&lt; " members." &lt;&lt; std::endl;
        echo(ss.str());

        return true;
    }
    return false;
}
</code></pre>

<p>So we just removed the entity from it's group with snatchIt set to false to prevent a loop. After that we simply updated the entity->LFDGroupID to the current group's id and that would be the end of it.</p>

<p>Sorry for the load of code.. not all of it is relevant but it allows you to follow the path the removing-an-entity function takes. My main question is; how do I go about quickly debugging access violations?</p>

<p>When the application crashes, the breakpoint ends up in a file called 'vector'</p>

<pre><code>size_type size() const
    {   // return length of sequence
    return (this-&gt;_Mylast - this-&gt;_Myfirst); //Breakpoint here.
    }
</code></pre>

<p><strong>UPDATE(Solution):</strong></p>

<p>I started by commenting out the various steps the Queue::removeFakeEntity() function takes to figure out where it all goes wrong. I immediately figured out the problem was with the line <code>lfdgroups.groupHeap[groupID]-&gt;removeMember(lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs[getrand(0,lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs.size()-1)],true);</code></p>

<p>So I cut it into pieces</p>

<pre><code>unsigned int entityID = lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs[getrand(0,lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs.size()-1)];
lfdgroups.groupHeap[groupID]-&gt;removeMember(entityID,true);
</code></pre>

<p>The error still occured. The breakpoint occured at a vector size return, so I isolated that;</p>

<pre><code>void Queue::removeFakeEntity()
{
    std::cout &lt;&lt; "size: " &lt;&lt; lfdgroups.groupHeap[groupID]-&gt;arrayOfEntityIDs.size() &lt;&lt; std::endl;
}
</code></pre>

<p>The error <em>still</em> occured. So I tried putting in the groupID manually.</p>

<pre><code>void Queue::removeFakeEntity()
{
    std::cout &lt;&lt; "size: " &lt;&lt; lfdgroups.groupHeap[1]-&gt;arrayOfEntityIDs.size() &lt;&lt; std::endl;
    std::cout &lt;&lt; "size: " &lt;&lt; lfdgroups.groupHeap[2]-&gt;arrayOfEntityIDs.size() &lt;&lt; std::endl;
    std::cout &lt;&lt; "size: " &lt;&lt; lfdgroups.groupHeap[4]-&gt;arrayOfEntityIDs.size() &lt;&lt; std::endl;
}
</code></pre>

<p>Works just fine! It had to be a problem with the groupID.</p>

<pre><code>void Queue::removeFakeEntity()
{
    std::cout &lt;&lt; "Heap size: " &lt;&lt; lfdgroups.groupHeap.size() &lt;&lt; std::endl;
}
</code></pre>

<p>That's odd, it shows '4'. But wait a second! Counting the first element (0) it should be 5, right? </p>

<p>Wrong, I started counting groupIDs at 1 because I wanted to reserve 0 as a return value. I should have just gone for NULL. I even thought about it when I made the decision yesterday. "I'm going to forget I did that!". Why don't I ever listen to myself?</p>

<p>So the problem was with <code>unsigned int groupID = getrand(0,lfdgroups.groupHeap.size()-1);</code> which, ironically, is the very first line of the function I was having issues with..</p>
