C++ Threading with multidimensional vectors - access violation - c++

I'm currently trying to get work done in a threaded member function of my class. Therefore it gets a 2d array as parameter and fills it in the member function. This gets repeated multiple times. Right after spawning the first thread I get an error with either read or write access violation. I tried different approaches to solve it, but can't get it to work. While I found nearly any problem already solved here, in this case I was unsuccessful finding something for quite a while now.
void myClass::process(Vector3D& out_stack, long filterFaktor){
long rowSize = this->input2D.size();
long colSize = this->input2D.at(0).size();
int filterPerRowCount = ceil((double)rowSize / filterFaktor);
int filterPerColCount = ceil((double)colSize / filterFaktor);
std::vector<std::thread> threadPool;
//create new filter
long currentrow = 0;
while (currentrow < rowSize) {
long currentcol = 0;
while (currentcol < colSize) {
Filter* nextFilter = &this->createNextFilter(currentrow, currentcol, filterPerRowCount, filterPerColCount);
out_stack.push_back(Vector2D());
Vector2D* nptr = &out_stack[out_stack.size()-1];
//Here we are calling the thread which leads to the access violation
threadPool.push_back(std::thread(&myClass::nextProcess, this, nextFilter, nptr, rowSize, colSize));
currentcol += filterPerColCount;
}
currentrow += filterPerRowCount;
}
//wait until threads have finished
for (int iThread = 0; iThread < threadPool.size(); iThread++) {
threadPool[iThread].join();
}
}
void myClass::nextProcess(Filter* nextfilter, Vector2D* out_Map, long rowCount, long colCount){
//Loops this part -> creates the rows and pushes them in the out_Map
std::vector<double> nextRowInMap;
//... Calculates sum
nextRowInMap.push_back(sum);
//Push row in vector -> This is where the error occurs
out_Map->push_back(nextRowInMap);
}
typedef std::vector<double> Vector1D;
typedef std::vector<Vector1D> Vector2D;
typedef std::vector<Vector2D> Vector3D;
I think I'm just missing knowledge in using Pointers in C++, cause I'm new to it.
Thanks in advance & best regards
EDIT
Tried it now this way, still doesn't work:
out_stack.push_back(Vector2D());
long index = out_stack.size() - 1;
threadPool.push_back(std::thread(&myClass::nextProcess, this, nextFilter, &out_stack, index, rowSize, colSize));
And in nextProcess:
out_stack->at(index).push_back(nextRowInMap);
EDIT
Solved with mutex. Additionally I needed to pass the filter not on reference.

You error is here:
out_stack.push_back(Vector2D());
Vector2D* nptr = &out_stack[out_stack.size()-1];
There is no guarantee that the object stays at the same address when you modify the vector.
When the vector has to grow it can allocate the internal memory on another address and move the objects in the vector to a new address. So the pointer can get invalid on the next push_back
You should pass the vector and index to the thread and access it each time you need it
out_stack[index].push_back(...)
It may be that after out_stack[index] and before push_back the vector gets modified and you are also operating on invalid memory. So you should protect accessing/modifying the vector with a std::mutex. I am not sure on that last part though if there is some thread safety guarantee there I don't know of.

Related

Access violation reading while using object pointers

At the beginning, my program creates a structure and a class that contain a struct and two int variables.
#define fullwidth 200
#define fullheight 200
typedef struct tiles
{
unsigned char red, green, blue;
char* name;
}tiles;
class Units
{
public:
int X_Pos;
int Y_Pos;
tiles MapColour;
}
After that, in the main part, I create a 2-dimensional array to use tiles as RGB containers for display, and an array of object pointers to follow any changes in the declared objects.
int i, j;
tiles fieldd[fullwidth][fullheight];
Units* DetectorField[fullwidth][fullheight];
Units Objects[10];
After that (now in main()), I upload both of the arrays with valid values, avoiding issues about that.
for (j=0;j<fullheight;j++)
{
for (i=0;i<fullwidth;i++)
{
fieldd[i][j] = BASE;
DetectorField[i][j] = NULL;
}
}
Same with the objects + adding object memory adress for pointers to be able to identify them through DetectorField:
for (i=0; i<9;i++)
{
Objects[i].X_Pos = i+2; //just some values, not important yet
Objects[i].Y_Pos = 2*i+2;
DetectorField[Objects[i].X_Pos][Objects[i].Y_Pos] = &Objects[i];
}
Most certainly, this is okay yet. But the problem comes now! In the next piece of codes, I check every elements of DetectorField; if the chosen element isn't NULL yet (which obviously means that it can be only the memory adress of an object, since it couldn't get any other values - if I know well), then put the MapColour variable to the array of structures.
for (j=0;j<fullheight;j++)
{
for (i=0;i<fullwidth;i++)
{
if(DetectorField[i][j] != NULL)
{
fieldd[i][j] = DetectorField[i][j]->MapColour;
}
}
}
At this point, MSVC gives this error message when I try to run it: Unhandled exception at 0x00411ed7 in Fallen Star.exe: 0xC0000005: Access violation reading location 0xccccccdc.
What did I do wrong? The operation inside the condition seems OK for me. Is the problem the way I use fieldd maybe?
You simply have access violation. You should debug your code, by Stepping Into and Stepping Over to find out where the access violation is coming from. The access violation says, you are trying to refer to NULL references. Make sure you allocate memory to your Objects before accessing them.
You have a for loop that assigns DetectorField[i][j] = NULL, meaning location [i][j] is a NULL reference. And then you have a reference DetectorField[Objects[i].X_Pos][Objects[i].Y_Pos]. You might have some access violation right there.
This loop:
for (i=0; i<9;i++)
{
Objects[i].X_Pos = i+2; //just some values, not important yet
Objects[i].Y_Pos = 2*i+2;
DetectorField[Objects[i].X_Pos][Objects[i].Y_Pos] = &Objects[i];
}
Does not seem to do a full initialization, because there are 10 elements in Objects and you only initialize 9 of them.
I think you want
for (i=0; i<10; i++)
Or even better
for (i=0; i<(sizeof(Objects)/sizeof(Objects[0])); i++)

Arrays and pointers in a template

I am attempting to write a template/class that has a few functions, but I'm running into what seems like a rather newbie problem. I have a simple insert function and a display values function, however whenever I attempt to display the value, I always receive what looks like a memory address(but I have no idea), but I would like to receive the value stored (in this particular example, the int 2). I'm not sure how to dereference that to a value, or if I'm just completely messing up. I know that vectors are a better alternative, however I need to use an array in this implementation - and honestly I would like to gain a more thorough understanding of the code and what's going on. Any help as to how to accomplish this task would be greatly appreciated.
Example Output (running the program in the same way every time):
003358C0
001A58C0
007158C0
Code:
#include <iostream>
using namespace std;
template <typename Comparable>
class Collection
{
public: Collection() {
currentSize = 0;
count = 0;
}
Comparable * values;
int currentSize; // internal counter for the number of elements stored
void insert(Comparable value) {
currentSize++;
// temparray below is used as a way to increase the size of the
// values array each time the insert function is called
Comparable * temparray = new Comparable[currentSize];
memcpy(temparray,values,sizeof values);
// Not sure if the commented section below is necessary,
// but either way it doesn't run the way I intended
temparray[currentSize/* * (sizeof Comparable) */] = value;
values = temparray;
}
void displayValues() {
for (int i = 0; i < currentSize; i++) {
cout << values[i] << endl;
}
}
};
int main()
{
Collection<int> test;
int inserter = 2;
test.insert(inserter);
test.displayValues();
cin.get();
return 0;
}
Well, if you insist, you can write and debug your own limited version of std::vector.
First, don't memcpy from an uninitialized pointer. Set values to new Comparable[0] in the constructor.
Second, memcpy the right number of bytes: (currentSize-1)*sizeof(Comparable).
Third, don't memcpy at all. That assumes that Comparable types can all be copied byte-by-byte, which is a severe limitation in C++. Instead:
EDIT: changed uninitialized_copy to copy:
std::copy(values, values + currentSize - 1, temparray);
Fourth, delete the old array when it's no longer in use:
delete [] values;
Fifth, unless the code is going to make very few insertions, expand the array by more than one. std::vector typically increases its size by a factor of 1.5.
Sixth, don't increment currentSize until the size changes. That will change all those currentSize-1s into currentSize, which is much less annoying. <g>
Seventh, an array of size N has indices from 0 to N-1, so the top element of the new array is at currentSize - 1, not currentSize.
Eighth, did I mention, you really should use std::vector.
This line is wrong:
memcpy(temparray,values,sizeof values);
The first time this line is run, the values pointer is uninitialized, so it will cause undefined behavior. Additionally, using sizeof values is wrong since that will always give the size of a pointer.
Another issue:
temparray[currentSize] = value;
This will also cause undefined bahavior because you have only allocated currentSize items in temparray, so you can only access indices 0 to currentSize-1.
There is also an error in your array access.
temparray[currentSize/* * (sizeof Comparable) */] = value;
Remember that arrays start at index zero. So for an array of length 1, you would set temparray[0] = value. Since you increment currentSize at the top of the insert function, you will need to do this instead:
temparray[currentSize-1] = value;

EXC_BAD_ACCESS when trying to delete valid pointer (xcode c++)

I have a template class called OrdinalObjectList which is simply a map with a key of int and object pointers. It's purpose is to provide an collection of object pointers that can be accessed by an ordinal key. Here is the class:
template <typename O>
class OrdinalObjectList {
public:
std::map<int, O*> List;
OrdinalObjectList() {};
virtual ~OrdinalObjectList()
{
// Need to delete the objects in the map
typename std::map<int, O*>::iterator i;
for (i = List.begin(); i != List.end(); i++)
{
O* d = i->second;
delete d;
}
};
On destruction of the OrdinalObjectList, the destructor loops through the map and deletes the objects. This has worked fine up until now, however it is currently receiving a EXC_BAD_ACCESS error when deleting the second of two objects in the collection.
On the first pass d is 'FSCE::Customer' * 0x10088e600 which delete's without issue. On the second pass, d is 'FSCE::Customer' * 0x100897e00 which, when delete'd causes the EXC_BAD_ACCESS. I can access the members of the second 'd' in the debugger. i.e. d->lifeid int 2, indicating that the FSCE::Customer object is a valid object and that 'd' is a valid pointer.
What steps should I take next to track down the cause of the EXC_BAD_ACCESS?
I can't tell for sure, but it is it possible your deleting the 1st and (nonexistent) 2nd items, rather than the 0th and 1st items? Make sure you're deleting what you think you're deleting.
EXC_BAD_ACCESS can easily be traced by enabling zombie objects.
For XCode 4.x see How do I set up NSZombieEnabled in Xcode 4?
For other versions of XCode you can find it on the internet.
Edit: Below is incorrect.
Not really an answer, however when I reduced the number of threads to 4, the problem goes away. Previously I had set the number of threads to 8, the boxen is Core i7, which is 4 cores with Hyper Threading.
I can only assume that there is a problem with Hyper Threading, either in the OSX kernel or LLVM. I have optimisations set to O3, at some point I will turn off optimisations and see if that works on 8 threads, however in the meantime, 4 threads is only 10% slower than 8, so I will stick with that so I can progress.
The problem was with a large array within the objects I was deleting. The array was created in the constructor and deleted in the destructor similar to this (data member names have been changed):
Matrix::Matrix(int maxa, int maxb, int maxc)
{
asize = maxa;
bsize = maxb;
csize = maxc;
matrixsize = a * b * c;
matrix = new double [matrixsize];
}
Matrix::~Matrix()
{
delete [] matrix;
}
So far so good, however in setting the values in the matrix I had a bug.
void Matrix::SetValue(int a,int b,int c,double value)
{
int index = (a * asize) + (b * bsize) + c;
matrix[index] = value;
}
The bug in another part of the code that set 'maxc' meant that sometimes index would be greater than matrixsize, which I discovered by adding a check and throw.
void Matrix::SetValue(int a,int b,int c,double value)
{
int index = (a * asize) + (b * bsize) + c;
if (index >= matrixsize) throw;
matrix[index] = value;
}
This would result in access to memory outside that which was allocated in the constructor, and when the delete was called, the EXC_BAD_ACCESS error being raised. The curious thing is why the EXC_BAD_ACCESS was not raised in Matrix::SetValue during execution, but I guess the answer has something to do with there being no bounds checking on array index offsets against the heap manager's memory bounds. If anyone can shed light on that I would be most interested, but for now, this answer is for anyone who finds this answer from a web search.

proper memory allocation for a 2D array in a class in C++

I am writing a C++ class that uses some fixed arrays, as well as some dynamically allocated arrays.
I was wondering if anybody can guide me for the proper way to allocate memory for the dynamic arrays , probably in the constructor/deconstructor, and also if I need to explicitly call them to make sure I don't get a seg fault.
Here is a simplified version of the related part of my code:
class Network {
public:
int n_nodes;
int user_index[MAX_USERS]; //a fixed array
int adjacency_matrix[][MAX_ITEMS];
//Network(int n_node, int** adjacency); //I would rather to set the element s in a function other than the constructor
Initializer(int n_node, int** adjacency);
~Netowrk();
}
So here are my specific question for this class:
1 - Can I have the 2D array adjacency_matrix[][] with undecided number of rows and columns until it's set by the user in the initializer function?
2 - where should I delete the 2D array? should I write it in the deconstructor? Should I call the deconstructor explicitly? Is there anything else I need to destroy in the deconstructor?
1 - Can I have the 2D array adjacency_matrix[][] with undecided number of rows and columns until it's set by the user in the initializer function?
Yes. The best way to do this, however, is not to use arrays at all. Instead, use std::vector, which manages the memory for you. There are two ways that you can do this. If you actually want to be able to use the [row][column] syntax to access elements, you'll need to use two dimensions of std::vectors:
std::vector<std::vector<int> > adjacency_matrix;
Once you know the dimensions, you can populate it:
adjacency_matrix.assign(rows, std::vector<int>(columns));
It is often easier to use a single-dimensional array (or a std::vector<int>) containing all of the elements and use row * row_count + column to access the element at index (row, column). This way, there are fewer dynamic allocations. You can wrap up the logic of accessing elements into a couple of helper functions.
2 - where should I delete the 2D array? should I write it in the deconstructor?
You don't have to delete anything if you use a std::vector. It cleans itself up.
Should I call the [destructor] explicitly?
No.
Is there anything else I need to destroy in the [destructor]?
Ideally, no. If you use the Standard Library containers, like std::vector and smart pointers, you shouldn't have to clean anything up. You should avoid trying to manage resources on your own in C++: there are library facilities to do this tedious task for you and you should take advantage of them.
1 - Can I have the 2D array adjacency_matrix[][] with undecided number of rows and columns until it's set by the user in the initializer function?
Yes you can. For example:
int* adjacency_matrix_;
int* getAdjacency(int i, int j)
{
if (!adjacency_matrix_)
return 0;
else
return adjacency_matrix_ + i*n_nodes + j;
}
Network()
: n_nodes(0),
adjacency_matrix_(0)
{}
void Initializer(int n_node, int** adjacency)
{
adjacency_matrix_ = new int[n_nodes * n_nodes];
// Copy over data.
}
As to whether you should, that depends on whether you have a reason for not using std::vector<>.
2 - where should I delete the 2D array? should I write it in the deconstructor?
Should I call the deconstructor explicitly?
Is there anything else I need to destroy in the deconstructor?
Yes, definitely free in the destructor using array operator delete:
~Network()
{
delete [] adjacency_matrix_;
}
No, your destructor will be called whenever the Network object itself goes out of scope. It is (very) rarely necessary to make an explicit destructor call.
No, all a destructor needs to explicitly release is whatever your explicitly acquire.
You may like the example matrix class I wrote in an answer to another question
The question itself was about good C++ design practices, but the chosen example was a multi-dimensional array.
There are several ways to do this.
The easiest way is to use vectors, and if you don't like to manage your own memory, this is perfect for you. However, because I like to manage my own memory, and I have found this method to be slow and cumbersome at times, I have learned of other ways.
The fastest way is to allocated a one dimensional array and treat it as you would a two dimensional array. Here is an example:
int *array = new int[width*height];
int get_array(int column, int row)
{
return array[row*width + column];
}
delete [] array;
This can be generalized to the nth-dimension:
int *array = new int[w1*w2*...*wn];
int get_array(int i1, int i2, ..., int in)
{
return array[in*(w1*w2*...*w(n-1)) + i(n-1)*(w1*w2*...*w(n-2)) + ... + i2*w1 + i1];
}
delete [] array;
If you want to be able to have different widths for each row, then you can make an array of pointers. This solution is slow to initialize and clean up, but flexible, tunable, and has relatively fast execution time. It can also be extremely dangerous if you make a mistake though.
int **array = new int*[height];
for (int i = 0; i < height; i++)
array[i] = new int[width(i)];
at which point, to access it, all you have to do is the customary
array[i][j]
however, to free this array you have to do it row by row
for (int i = 0; i < height; i++)
delete [] array[i];
delete [] array;
This can also generalize to the nth dimension.
int **....*array = new int**...*[w1];
for (int i1 = 0; i1 < w1; i1++)
{
array[i1] = new int**..*[w2];
for (int i2 = 0; i2 < w2; i2++)
{
array[i1][i2] = new int**.*[w3];
...
for (int in = 0; in < wn; in++)
array[i1][i2]...[in] = new int[wn];
}
}
for (int i1 = 0; i1 < w1; i1++)
{
for (int i2 = 0; i2 < w2; i2++)
{
...
for (int in = 0; in < wn; in++)
delete [] array[i1][i2]...[in];
...
delete [] array[i1][i2];
}
delete [] array[i1];
}
delete [] array;
This kind of setup tends to wreak havoc on memory. Just a two dimensional array of these would result in width+1 separate arrays to be malloc-ed. It would be faster to just malloc one big array and figure out the indices yourself.

Access Violation with static arrays?

I need to parallelise an application using win32 threads. One of the portions of the code involves modifying an static array using threads.
I pass the array as a parameter like this:
struct threadParameter {
float **array;
int row;
}
An example code would be like this:
// Main
float data[100][100]
for (int i = 0; i < 100; i ++) {
tp = (*threadParameter) new threadParameter;
tp->array = (float **) data;
tp->row = i;
AfxBeginThread... // Begin thread code
}
// Thread Code
UINT myThread(LPVOID param) {
threadParameter *pp = (threadParameter *) param;
for (int j = 0; j < 100; j ++) {
pp->array[pp->row][j] = NEWVALUE;
}
}
However, when executing the project, I get an "Access Violation Error" when I try to acceess the array via the **array pointer. This problem does not occur if the array data is
dynamic. Is there any way to sort this problem out (I am not allowed to change the array data from static to dynamic)?
Static arrays are NOT pointers to pointers -- the entire array is a single huge chunk of data, and addressable with a single pointer, namely, the pointer to the base of the array. Hence
tp->array = (float **) data;
is incorrect, because you're dereferencing a number inside the array. (The fact that you needed to cast also should've raised a red flag, since arrays are implicitly converted to the appropriate pointer types.)
That's why the common phrase "arrays are just pointers" is incorrect; it's half-true for single-dimensional arrays, but completely false with multidimensional arrays. If you need to use two indices, convert a single index into a row-column index by multiplying the row by the row size, then adding the column and indexing into the array with a pointer.