Access violation when accessing vector element's member function - c++

I am coding an MFC applcation using VS2012.
I have a vector of Bitmap*, I insert elements in a for loop, and then, if I try to access some element's function outside the loop it will give me an access violation.
The strange thing is if I try to access it inside the loop, it works just fine.
In both examples m_VectorImageNames is already filled with some image files paths, it is not the problem.
The following code gives the access violation (at the last line):
std::vector<Bitmap *> vectorImages;
for (int i = 0; i < nImages; i++)
{
Bitmap img(m_VectorImageNames[i]);
vectorImages.push_back(&img);
}
int imgWidth= vectorImages[0]->GetWidth();
If I put the GetWidth inside the loop, it returns the correct value:
std::vector<Bitmap *> vectorImages;
for (int i = 0; i < nImages; i++)
{
Bitmap img(m_VectorImageNames[i]);
vectorImages.push_back(&img);
int imgWidth= vectorImages[0]->GetWidth();
}
I have tried a few things already, with no success:
Initializing the vector with the size it will have and then inserting each bitmap in its corresponding position (with hope that it was an allocation problem).
Looping using iterators
Making the vector a class member variable
Does anyone have a clue of what may be happening?

The BitMap object img is defined on the stack inside the loop. The pointer to img is pushed into the vector. Then the memory storage that the pointer elements point to in the vector is lost once the loop has terminated.
Use new (the operator for dynamic memory allocation) to store the bitmaps.
for (int i = 0; i < nImages; i++)
{
Bitmap *img = new BitMap(m_VectorImageNames[i]);
vectorImages.push_back(img);
...
}
Possibly better (instead of using raw pointers) would be to use a memory-managed pointer such as std::shared_ptr. This depends on your requirements.

Related

Segmentation fault: 11 c++ when using vector

i am trying to write a program for my university project the program is supposed to do first come first serve scheduling i have thought a lot about this function but i don't know how to make it work, i always get Segmentation fault: 11, i also tried to use temp.at(j) but it gave me Segmentation fault: 6, and i tried to minimise the vector so it would be in-bound by declaring the vectors outside the function, then use temp.size() instead of Processes but it also did't work.
void FCFS(Process ProcessDetails[], int Processes)
{
vector<int> temp;
vector<int> temp1;
int first = 0; //first value to compare with.
for(int j = 0; j < Processes; j++){ // to make sure that it passes through all elements.
for(int i = 0; i < Processes; i++){ // pass each PID and Burst time to vector temp and temp1.
if(ProcessDetails[i].ArrivalTime == first){
temp.operator[](j) = ProcessDetails[i].PID;
temp1.operator[](j) = ProcessDetails[i].BurstTime;
}
}
first++;// increase first value to declare the round is finished and start a new one.
}
for(int i = 0; i < Processes; i++){ // pass the sorted vector values back to the arrays.
ProcessDetails[i].PID = temp.operator[](i);
ProcessDetails[i].BurstTime = temp1.operator[](i);
}
}
the program works fine until it reaches this function, please help.
The behaviour of a vector's operator[]() is undefined if it is used to access elements that do not exist.
Since you have used default-constructed vectors, their size is zero - so they have no elements to access.
If you use the .at() member function, it will check the index and throw an exception (of type std::out_of_range, which is declared in the standard header <stdexcept>) when indices are invalid. You can confirm that by wrapping the code in an appropriate try/catch block.
To eliminate the problem, you need to reize the vector (e.g. add elements to it using push_back(), resize it using resize(), etc) before using operator[](). And ensure the index is valid, since operator[]() does not resize a std::vector.
Also, temp[j] is equivalent to temp.operator[](j). For types that supply an operator[]() function, the compiler handles turning expressions like temp[j] into a call of temp.operator[](j).
Your vectors have no elements.
Using the vector operator[] will therefore fail.
Use push_back, emplace, resize, or some other function to add elements to the vectors.
you will have to change your vector assignment to
if(ProcessDetails[i].ArrivalTime == first){
temp.push_back(ProcessDetails[i].PID);
temp1.push_back(ProcessDetails[i].BurstTime);
}

Assign values from vector to dynamic array (C++)

I have a vector of vertices of a line called lineVertices and I am going to pass this data to draw an OpenGL shape, so this vector must be in the form of an array, I'm assuming. I've tried the following code:
float* lineArray = new float[lineVertices.size()]();
for (unsigned i = 0; i < lineVertices.size(); i++) {
lineArray[i] = lineVertices.at(i);
}
However, it appears that the each element of the vector is getting assigned to the first element of the array only. Even though the lineArray identifier is a pointer to the first element, is there another way to access the different elements of the dynamic array?
If it helps, when I am debugging, it says that the size of lineArray is always 1, although lineVertices' size is clearly greater than 1.
I have also tried the code below, but this also does not work.
float* lineArray = &lineVertices[0];
Any help is appreciated!
You can pass a std::vector directly to OpenGL functions taking a pointer to an array. Just use the ::data() member function. Example:
std::vector<float> vec = ...;
glVertex2fv(vec.data()); // only uses the first two elements
OpenGL functions like this take a pointer to one or more elements. This doesn't have to be a raw array created with new; it just has to be a pointer to a consecutive list of elements. Use vector.data() to get a pointer to a std::vector's contents (first element).
If you really want to create a new array with manual memory management, you can do this (same effect as the code you posted):
float* arr = new float[vec.size()]; // NO () - not a constructor, but operator new[]
for (size_t i = 0; i < vec.size(); i++) {
arr[i] = vec[i];
}

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++)

Which would be better: A unique_ptr to a 2D array or a 2D array of unique_ptrs?

I'm currently in the middle of making an old project of mine memory-safe.
In this project I have a 2D array populated with pointers to instances of my own class Block.
declared like so:
Block* gemGrid[xMax][yMax];
and populated later like so:
for(int i = 0; i<8; i++)
{
for(int j = 0; j<8; j++)
{
//do stuff here
gemGrid[i][j] = new Block(i,j, gridOffset);
}
}
This works fine.
I had the idea of creating a 2D array of unique_ptr<Block> instead of Block*.
Which i decided to declare like so:
unique_ptr<Block> gemGrid[xMax][yMax];
and populate like so:
for(int i = 0; i<8; i++)
{
for(int j = 0; j<8; j++)
{
gemGrid[i][j].reset( new Block(i,j, gridOffset));
}
}
However when I try this the compiler decides to completely ignore the second for loop (the 'j' incremented section), and create only a one dimensional array.
Which leads me to ask, does C++ have a problem with unique_ptrs in 2D arrays? And should I just stick with a 2D array of pointers to Blocks, and have one unique_ptr make sure this array is killed-of when it goes out of scope?
C++ has no objection whatever to a 2-D array of unique_ptr.
The two alternatives you offer don't seem like real alternatives to me. If you have a unique_ptr to a 2-D array of Block*, and you allocate xMax * yMax instances of Block using new and store pointers to them in your array, then who or what is going to free those instances of Block? Certainly the unique_ptr is not. So the answer to "should I just do that" is almost certainly "no", because you'll have memory leaks.
The most "obvious" way to allocate a 2-D layout of instances of Block is to define a 2-D array of Block (either using a builtin array or std::array if available). If you can identify anything about that that doesn't suit you, then someone can suggest an alternative way for your old code to avoid memory leaks.
[In response to a comment above] Having done Block gemGrid[xMax][yMax];, you can get a pointer to one of your Block objects, if you need one, like this: &gemGrid[i][j]. Needing a pointer has absolutely nothing to do with memory allocation. Pointers are the means by which new lets you access the objects it allocates, but you can take a pointer to an object regardless of how it is allocated.

C++ 2DArray Objects; Pointers and Array Problems

This problem is from a solved problem in my old question, which is from:
C++ Inserting 2D array Object into another 2D array Object
But also created a new problem for me. Please read the question and the solution in the link to understand my problem. The solution in the previous question was to make my Data Member Function into a pointer to pointer, to allow the pass into the other Data Member Function. But while fixing that, the first Data Member Function which is smallerArray.extractPiece() now only return address of the pointer to the pointer and not the content of those pointers. I need the content in order for my 2nd Data Member Function largerArray.extractArray(result) to work properly, as I attempt run the code and gave an Window Error, and not a Compile Error.
Does anyone know how to extract the content of the smallerArray.extractPiece() and instead of getting of the address, and is there isn't, does anyone have any other methods of creating a 2D-Array Object?
void Grid::extractArray( int** arr )
{
for(int i = 0; i < xGrid ; ++i) {
for (int j = 0; j < yGrid ; ++j) {
squares[i][j] = arr[i][j];
}
}
}
The smaller array int**arr does not have as many elements as the Grid.
xGrid and yGrid are too large to use as indices for arr[][].
You must pass the complete smaller array object into the extractArray() function and use the sizes from this object for the copy function.
void Grid::extractArray( const Piece & piece)
{
for(int i = 0; i < piece.xGrid ; ++i) {
for (int j = 0; j < piece.yGrid ; ++j) {
squares[i][j] = arr[i][j];
}
}
}
Right now, your problem seems a bit underspecified. How large of a 'piece' do you expect from the smaller array, and where in the larger array do you want to insert it?
It may make things easier if you create a 2D array object or class (or struct)
class BaxMatrix {
public:
int m_Data[4][4];
}
with a little work you could build dynamic structures or use STL structures as desired.
The data, and the reference to the data are two different animals. It's best for you to clarify each of their roles in your thinking, before proceeding forward.