Reputation: 605
I am getting unhandled exception and access violation reading location error. But sometimes it is executing perfectly. Am i passing vector and vector iterators properly? What might be the possible cause of error.
struct DataStructure
{
MapSmoother *m1;
std::vector<Vertex *> v1;
std::vector<Vertex *>::iterator vit_f;
std::vector<Vertex *>::iterator vit_e;
DataStructure() {
m1 = NULL;
v1;
vit_f;
vit_e;
}
};
DWORD WINAPI thread_fun(void* p)
{
DataStructure *input = (DataStructure*)p;
while ( input->vit_f != input->vit_e ) {
Vertex *v = *((input->vit_f)++);
(*(input->m1)).relax(v);
}
return 0;
}
int main()
{
//Read and encode color to Mesh
// msmoother is an object
DataStructure* input = new DataStructure();
input->m1 = &msmoother;
for(int i = 0; i < 7; ++i) {
for(int color = 1; color <= k; color++) {
std::vector<Vertex *> verList;
//all the vertices with the same color index will be stored in verList vector
input->v1 = verList; //Copied to structure
std::vector<Vertex *>::iterator vit1 = verList.begin();
std::vector<Vertex *>::iterator vit2 = verList.end();
input->vit_f = vit1;
input->vit_e = vit2;
HANDLE hThread[50];
cout << " Processing for color: " << color << endl;
for(int j = 0; j < 50; ++j){
hThread[j] = CreateThread(0,0,(LPTHREAD_START_ROUTINE)&thread_fun,input,0,NULL);
}
WaitForMultipleObjects(THREAD_COUNT,hThread,TRUE,INFINITE);
//clear verList vector
//Close Handles to all threads
}
}
}
Upvotes: 1
Views: 134
Reputation: 66254
No, you're not passing them in correctly.
This code:
input->v1 = verList; //Copied to structure
Makes a copy of the vector, which is intentional by the looks of it. Since the vector contains mere pointers to actual data, you're just making a copy of a bunch of pointers. However, the followup code:
std::vector<Vertex *>::iterator vit1 = verList.begin();
std::vector<Vertex *>::iterator vit2 = verList.end();
input->vit_f = vit1;
input->vit_e = vit2;
is where the problem lays. The iterators you're setting in your input
object are, in fact, from the local verList
; not from your input->v1
list.
Try:
input->vit_f = input->v1.begin();
input->vit_e = input->v1.end();
Addendum
Updated for OP to avoid race condition and uneeded vector copy.
First, redefine DataStructure
as:
struct DataStructure
{
MapSmoother *m1;
std::vector<Vertex *>::iterator first, last
DataStructure() : m1(NULL) {}
};
Next, define your thread function as:
DWORD WINAPI thread_fun(void* p)
{
DataStructure *input = static_cast<DataStructure*>(p);
if (input && input->m1)
{
for (std::vector<Vertex *>::iterator it = input->first
it != input->last; ++it)
{
input->m1->relax(*it);
}
}
delete input;
return 0;
}
And finally, invoke this as: (inside your loops)
// all the vertices with the same color index will be stored in verList vector
std::vector<Vertex *> verList;
// ... store vector data ...
cout << " Processing for color: " << color << endl;
HANDLE hThread[50] = {NULL};
for(int j = 0; j < _countof(hThread); ++j)
{
DataStructure *input= new DataStructure;
input->first = verList.begin();
input->last = verList.end();
input->m1 = &msmoother
hThread[j] = CreateThread(0,0,(LPTHREAD_START_ROUTINE)&thread_fun,input,0,NULL);
}
WaitForMultipleObjects(THREAD_COUNT,hThread,TRUE,INFINITE);
Or something like that. I just hammered this online so I've no idea if it even compiles, but should hopefully give a decent enough idea to you. Every thread gets its own pair of iterators into the verList
array, and as such concurrent access. note: they cannot modify the vector; only use it. The structure they get the iterators in is allocated by the creator-thread, but owned by the thread itself, which is ultimately responsible for destroying it.
Upvotes: 2
Reputation: 95385
I'm a C++ noob, so I may be wrong but I think the problem may be here:
std::vector<Vertex *>::iterator vit1 = verList.begin();
std::vector<Vertex *>::iterator vit2 = verList.end();
input->vit_f = vit1;
input->vit_e = vit2;
You are passing around iterators to verList
rather than to the vector that has been copied to the DataStructure
. I think what you want here is:
input->v1 = verList; // copy to structure
input->vit_f = input->v1.begin();
input->vit_e = input->v1.end();
Upvotes: 2