I face the "unhandled exception access violation reading location", after i searched and realize that the problem reason from using vectors, but still i didn't solve it yet.
in .h i defined the following:
struct inside
{
double y;
vector <int> values;
};
struct outside
{
int x;
vector <inside> subInfo;
vector <double> d;
};
in .cpp:
vector <outside> mainInfo;
....
// method_inti called one time just ...
method_inti()
{
for(int i=1;i<=4;i++)
{
outside obj;
obj.x = i;
mainInfo.push_back(obj);
}
}
....
// method fill called many times (very large number of calls .. )
method_fill()
{
...
for(i = 1; i <= 4; i++)
{
for (int j=0;j< mainInfo.size();j++) // here surly size = 4
{
if(mainInfo[j].x == i)
{
inside obj;
obj.y = i+1;
obj.values.push_back(10.0);
mainInfo[j].d.push_back(5.0);
mainInfo[j].subInfo.push_back(obj);
}
}
}
...
}
// update n val method also called many times..
updateNval_method(int t)
{
double n;
for (int i=0; i< mainInfo.size();i++)
{
if(mainInfo[i].x == t)
{
n= mainInfo[i].d[(mainInfo[i].d.size())-1];
}
}
}
In the line n= mainInfo[i].d[(mainInfo[i].d.size())-1]; you're subtracting 1 from d.size() to get an array index, but you have no guarantee that d.size() >= 1.
If d happens to contain no elements, you're trying to access an array index of -1, which will throw that exception.
Related
Exception thrown: read access violation.
_My_data was 0xFFFFFFFFFFFFFFE7.
i get this exception when i run this code:
b.setOnAction([&](Bullet* b)
{
for (int j = 0; j < 10; j++)
{
Bullet b1;
b1.init();
bullets.push_back(b1);
}
}
);
it works when adding one bullet:
b.setOnAction([&](Bullet* b)
{
Bullet b1;
b1.init();
bullets.push_back(b1);
}
);
setOnAction sets a std::function variable inside the Bullet class that it calls in its update function.
here is the Bullet class:
class Bullet
{
private:
std::function<void(Bullet*)> mOnAction;
public:
void setOnAction(std::function<void(Bullet*)> func) { mOnAction = func; };
void init()
{
mOnAction = [](Bullet* b) {};
}
void update()
{
mOnAction(this);
}
};
bullets is a vector full of Bullet Objects.
Here is the main function:
int main()
{
std::vector<Bullet> bullets;
for (int i = 0; i < 10; i++)
{
Bullet b;
b.init();
b.setOnAction([&](Bullet* b)
{
for (int j = 0; j < 10; j++)
{
Bullet b1;
b1.init();
bullets.push_back(b1);
}
}
);
bullets.push_back(b);
}
while (true)
{
for (int i = bullets.size() - 1; i >= 0; i--)
{
Bullet& b = bullets[i];
b.update();
}
}
return 0;
}
I managed to fix this by adding bullets to a temporary vector and adding from the temporary vector to the main bullets vector
Something like this:
**// Temporary vector created besides main bullets vector
std::vector<Bullet> bulletsToAdd;**
b.setOnAction([&](Bullet* b)
{
for (int j = 0; j < 10; j++)
{
Bullet b1;
b1.init();
**//Add to the temp vector
bulletsToAdd.push_back(b1);**
}
}
);
while (true)
{
**// Add everything In the temp vector to the main vector
for (auto& b : bulletsToAdd)
bullets.push_back(b);
// Reset temp vector
bulletsToAdd.clear();**
for (int i = bullets.size() - 1; i >= 0; i--)
{
Bullet& b = bullets[i];
b.update();
}
}
The reference Bullet& b in main is only valid as long as bullets isn't resized, when the capacity of bullets increases all objects are deleted. The mOnAction member that you are calling through therefore becomes invalid when you push_back too many elements. As the references captured in the lambda are stored in the std::function your code crashes when it tries to access the bullets reference.
Address sanitizer can help debug these issues by crashing as soon as possible after your code has done something wrong: https://godbolt.org/z/a83Pd9e85
https://leetcode.com/problems/merge-sorted-array/
In this leetcode question, this is the logic, I used
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = 0;
int j = 0;
int k = 0;
vector<int> ans;
while (i<m && j<n) {
if (nums1[i] < nums2[j]){
ans[k++] = nums1[i++];
}
else {
ans[k++] = nums2[j++];
}
}
while (i<m) {
ans[k++] = nums1[i++];
}
while (j<n) {
ans[k++] = nums2[j++];
}
for (int h = 0; h<(m+n); h++) {
nums1[h] = ans[h];
}
}
};
while running the code, I get this runtime error.
Error Image
How do I solve this
This is a vector of size zero
vector<int> ans;
This code attempts to change an element of the size zero vector.
ans[k++] = nums1[i++];
That's the cause of your error.
If you want to add an element to the end of a vector use push_back
ans.push_back(nums1[i++]);
C++ vectors don't change size automatically, you have to use push_back or resize or insert or something similar.
Alternatively make the vector the correct size to begin with
vector<int> ans(m + n);
though I prefer the push_back method myself.
I just want to create a simple C++ struct that has an int index and an int grayValue .The function is given the vector with the gray values. When I try to compile it I get a segmentation fault, does anyone know why? (didn't sort the vector) Thank you.
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct;
for (int i = 0; i<grayValues.size();i++)
{
grayStruct[i].originalIndex= i;
grayStruct[i].grayValue= grayValues[i];
}
return grayStruct;
}
int main() {
vector <int> grayVals={411,21,78,23};
vector <gray> grayStruct=createStruct(grayVals);
// sort(grayStruct);
for (int i = 0; i < grayStruct.size(); i++)
{cout << grayStruct[i].originalIndex<<' '<<grayStruct[i].grayValue;
cout<<endl;
}
return 0;
}
It is because you are using elements of grayStruct, which actually doesn't exist, in the function createStruct.
You have to create elements before use or use push_back() to create elements.
Create elements via the constructor:
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct(grayValues.size()); // add number of elements to create
for (int i = 0; i<grayValues.size();i++)
{
grayStruct[i].originalIndex= i;
grayStruct[i].grayValue= grayValues[i];
}
return grayStruct;
}
Create elements via resize():
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct;
grayStruct.resize(grayValues.size()); // create elements
for (int i = 0; i<grayValues.size();i++)
{
grayStruct[i].originalIndex= i;
grayStruct[i].grayValue= grayValues[i];
}
return grayStruct;
}
Add elements one-by-one via push_back():
vector<gray> createStruct( vector<int> grayValues)
{
vector <gray> grayStruct;
for (int i = 0; i<grayValues.size();i++)
{
gray value;
value.originalIndex= i;
value.grayValue= grayValues[i];
grayStruct.push_back(value); // add an element
}
return grayStruct;
}
I am trying to learn c++. I have created a vector class vec and I am trying to implement a method to compute the dot product.
It compiles fine but I get a segmentation error when running it. I have pinned the x(i) reference in the dot product method down as the cause, but I have no idea why. I gather it is something about accessing memory incorrectly, but I have no idea what I am doing incorrectly nor what the correct way would be.
My vector class:
class vec{
private:
vector<double> data;
int n; // size
public:
vec (int s) { n = s; data.reserve(n); }
double get(int i) { return data[i]; }
void set(int i, double val) { data[i] = val; }
int size() { return n; }
double operator[] (int i) { return get(i); }
double operator() (int i) { return get(i); }
double dot (vec x) {
assert(n == x.size());
int z = 0;
for (int i = 0; i < n; i++){
z += data[i] * x(i);
}
return z;
}
};
I am trying to use it like so:
int main(int argc, char *argv[]) {
vec x = vec(3);
x.set(0, 1);
x.set(1, 1);
x.set(2, 2);
vec y = vec(3);
y.set(0, 2);
y.set(1, 2);
y.set(2, 3);
double z = x.dot(y);
}
Change this:
data.reserve(n);
To this:
data.resize(n);
The reserve does not create the items in a vector. All it does is increase the capacity. To actually create n objects up front, you use resize.
Also on a side note, I highly suggest you not use extraneous variables such as n to keep track of a vector's size. Use the vector::size() function instead. The reason is that you're risking bugs if for some reason n is not updated correctly.
Thus this should be your constructor:
vec (int s) : data(s) {}
and dump the n member variable.
In this clause:
vec y = vec(3);
y.set(0, 2);
y.set(1, 2);
y.set(2, 3);
You're setting index 3, which is out of bounds of this vector. To fix it, either initialize vec to be of length 4, or index somewhere else. :)
You should also be resizing instead of reserving, but getting this wrong shouldn't cause a segfault. It should just confuse people.
I'm new to C++, this is my first week since the upgrade from fortran. Sorry if this is a simple question, but could someone help me with operator overloading. I have written a program which has two classes. One object contains a vector and two scalars, the other class simply contains the first object. In a test implementation of this code I suspect the operator overloading to be at fault. The program tries to accomplish the following goals:
1) Initialize first structure.
2) Initialize a second structure containing the initialized first structure. After this is imported, the value val0 = 10 is added to every element of the vector in the enclosing structure, structure2.structure1 .
3) Output structure1 and structure2 variables to compare.
For this simple program my output is:
100
100
0
0
0 0 10
1 1 11
2 2 12
3 3 13
...
I was expecting:
100
100
0
10
0 0 10
1 1 11
2 2 12
3 3 13
...
Clearly my overloaded = operator is copying my vector properly, but one of the scalars? Could someone help?
#include <iostream>
using namespace std;
typedef double* doublevec;
// This first class contains a vector, a scalar N representing the size of the vector, and another scalar used for intializing the vector.
typedef class Structure1
{
int N, vec0;
doublevec vec;
public:
// Constructor and copy constructor.
Structure1(int Nin, int vecin) : N(Nin), vec0(vecin) { vec = new double [N]; for(int i = 0; i < N; i++) { vec[i] = i + vec0; } }
Structure1(const Structure1& structurein);
// Accessor functions:
int get_vec0() { return vec0; }
int get_N() { return N; }
doublevec get_vec() { return vec; }
// Overide equivalence operator:
Structure1& operator=(const Structure1& right)
{
//Handle Self-Assignment
if (this == &right) return *this;
N = right.N;
vec0 = right.vec0;
for (int i = 0; i < N; i++)
{
vec[i] = right.vec[i];
}
return *this;
}
// Destructor:
~Structure1() { delete []vec; }
} Structure1;
Structure1::Structure1(const Structure1& structurein)
{
N = structurein.N;
vec = new double[N];
for(int i = 0; i < N; i++)
{
vec[i] = structurein.vec[i];
}
}
// This class just contains the first structure.
typedef class Structure2
{
Structure1 structure;
// Mutator Function:
void mutate_structure();
public:
// Constructor:
Structure2(const Structure1& structurein) : structure(structurein) { mutate_structure(); }
// Accessor Function:
Structure1 get_structure() { return structure; }
// Destructor:
~Structure2() {}
} Structure2;
void Structure2::mutate_structure()
{
int N = structure.get_N();
Structure1 tempstruct(N,10);
structure = tempstruct;
}
int main (int argc, char * const argv[])
{
const int N = 100;
Structure1 structure1(N,0);
Structure2 structure2(structure1);
cout << structure1.get_N() << endl;
cout << structure2.get_structure().get_N() << endl;
cout << structure1.get_vec0() << endl;
cout << structure2.get_structure().get_vec0() << endl;
for(int i = 0; i < N; i++)
{
cout << i << " " << structure1.get_vec()[i] << " " << structure2.get_structure().get_vec()[i] << endl;
}
return 0;
}
it looks like vec0 isn't initialized by your copy constructor...
Try modifying your copy constructor to:
Structure1::Structure1(const Structure1& structurein)
{
N = structurein.N;
vec = new double[N];
for (int i = 0; i < N; i++)
{
vec[i] = structurein.vec[i];
}
// ADD THIS LINE
vec0 = structurein.vec0;
}
Your copy-constructor Structure1::Structure1(const Structure1 &) doesn't copy vec0. It's not getting initialised at all, so gets whatever is in memory.
Also, you might want to check Structure1's operator=. If you assign a large vector to a small vector, then you'll potentially overflow the array in the destination. You might need to reallocate memory in operator=.