Access Violation Reading Location
I have a problem with VC++, simply, I hate it haha. My code seems to be running all fine on my Mac but when I try to run it in VC++, I get this error in debug:
Windows has triggered a breakpoint in Assignment1-FINAL.exe.
This may be due to a corruption of the heap, which indicates a bug in Assignment1-FINAL.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while Assignment1-FINAL.exe has focus.
I know for a fact I haven't pressed F12 so I am not sure why I am getting this... Then, when I try to run it in Release mode, I get this:
Unhandled exception at 0x00401473 in Assignment1-FINAL.exe: 0xC0000005: Access violation reading location 0x00347015.
This is the code I am using:
int countPointsAboveThreshold(point * points, double threshold_distance) {
int i = 1;
int count = 0;
while (points[i - 1].end != true) {
point pointOne = points[i -1];
point pointTwo = points[i];
double distance = distanceBetweenTwoPoints(pointOne, pointTwo);
if (pointTwo.end == true) {
if (distance > threshold_distance) {开发者_如何转开发
count++;
return count;
} else {
return count;
}
} else if (distance > threshold_distance) {
count++;
}
i++;
}
return count;
}
int totalPoints(point * points) {
int i = 0;
while (points[i].end != true) {
i++;
}
return i + 1;
}
point * findLongPaths(point * points, double threshold_distance) {
int i = 1;
int locationToStore = 0;
int pointsAboveThreshold = countPointsAboveThreshold(points, threshold_distance);
point * pointsByThreshold = new point[pointsAboveThreshold];
pointValues * pointsToCalculate = new pointValues[pointsAboveThreshold];
while (points[i - 1].end != true && i < pointsAboveThreshold) {
point pointOne = points[i - 1];
point pointTwo = points[i];
//Check to see if the distance is greater than the threshold, if it is store in an array of pointValues
double distance = distanceBetweenTwoPoints(pointOne, pointTwo);
if (distance > threshold_distance) {
pointsToCalculate[i - 1].originalLocation = i - 1;
pointsToCalculate[i - 1].distance = distance;
pointsToCalculate[i - 1].final = pointTwo;
pointsToCalculate[i - 1].stored = false;
//If the final point has been calculated, break the loop
if (pointTwo.end == true) {
pointsToCalculate[i].end = true;
break;
} else {
pointsToCalculate[i - 1].end = false;
i++;
continue;
}
}
}
if (points[0].end == true && pointsAboveThreshold == 0) {
point emptyPoint;
emptyPoint.x = 0.0;
emptyPoint.y = 0.0;
emptyPoint.end = true;
pointsByThreshold[0] = emptyPoint;
return pointsByThreshold;
}
//Find the point with the lowest distance
int j = 2;
//EDITED
pointValues pointWithLowest;
pointWithLowest = pointsToCalculate[0];
while (pointsToCalculate[j - 1].end != true) {
for (int k = 1; pointsToCalculate[k - 1].end != true; k++) {
if (pointsToCalculate[k - 1].stored == true) {
k++;
continue;
} else {
if (pointsToCalculate[k - 1].distance > pointWithLowest.distance) {
pointWithLowest = pointsToCalculate[k - 1];
k++;
continue;
} else if (pointsToCalculate[k - 1].distance == pointWithLowest.distance) {
if (pointWithLowest.originalLocation < pointsToCalculate[k - 1].originalLocation) {
pointWithLowest = pointsToCalculate[k - 1];
k++;
continue;
} else {
k++;
continue;
}
} else {
pointWithLowest.stored = true;
pointsByThreshold[locationToStore] = pointWithLowest.final;
locationToStore++;
break;
}
}
}
//DEBUGGER STOPS HERE
j++;
}
delete[] pointsToCalculate;
return pointsByThreshold;
}
And this is the main function:
point *longest_calculated = findLongPaths(p, 1.1);
std::cout << "Should equal " << longest[1].y << ": " << longest_calculated[1].y;
delete longest_calculated;
cin.get();
return 0;
Inital thoughts: Where's the asserts? Your accessing Points* in countPointsAboveThreshold() as an array, but do no bounds checking at all to make sure you aren't pass the array's end. This would be my first area of checking for memory stomping action. Also, straight pointer calls are very C. Heck, you aren't check bounds in any of your array calls. Dangerous...
Newing arrays of length 0 may or may not be safe. I'd be careful of that.
Heck anytime I see [i - 1] in a statement I get nervous. Very easy to read garbage at i == 0
i,j,k loops with quadrouple nested ifs mixed with continues and a break? No. Rethink that logic. It is way, WAY too complicated.
You are early returning with memory allocated in pointsToCalculate[]. Memory leak there.
Might I suggest breaking your last function into multiple parts to simplify the logic?
Man I hate K&R style brackets. Your choice though - not here to start that holy war :P
Beyond that, I'd go with my first suggestion and make sure that your end bool is set always and that you aren't going out of bounds. As previously suggested, stl::vector and a few references (preferably const) are your friend here.
You posted this as C++ but it seems to be using very little of what C++ actually is all about: objects. This code reads much more like C.
Just some notes:
- With C++ you don't need to do
typedef struct {...} point
, doingstruct point {...}
does what you are trying to do. - If you use a stl::vector instead of a c-array then your loops will become much simpler and you won't need your function
totalPoints()
. You can also get rid of the member variableend
frompoint
andpointValues
- You are creating a lot of variables on the heap rather than on the stack for no good reason. With
stl::vector
(or other standard containers), local variables, and references you can greatly simplify your memory management and avoid strange crashes such as these.
I'll take a deeper look at your code and see if I can give you some more specific guidance but you really should do some further reading into what C++ provides over C. I'd take a look at cplusplus.com and the C++ FAQ. There are also some excellent book suggestions here.
This part of your code sounds odd to me:
if (distance > threshold_distance) {
pointsToCalculate[i - 1].originalLocation = i - 1;
pointsToCalculate[i - 1].distance = distance;
pointsToCalculate[i - 1].final = pointTwo;
pointsToCalculate[i - 1].stored = false;
...
I think you need to use another index variable (other than i - 1) to populate pointsToCalculate!
I would rewrite this part something like this:
int i = 1;
int index = 0;
// if points[i - 1].end is true how you could access points[i] ?
while (points[i].end != true && i < pointsAboveThreshold) {
point pointOne = points[i - 1];
point pointTwo = points[i];
//Check to see if the distance is greater than the threshold, if it is store in an array of pointValues
double distance = distanceBetweenTwoPoints(pointOne, pointTwo);
if (distance > threshold_distance) {
pointsToCalculate[index].originalLocation = i - 1;
pointsToCalculate[index].distance = distance;
pointsToCalculate[index].final = pointTwo;
pointsToCalculate[index].stored = false;
++ index;
}
++i;
}
pointsToCalculate[index].end = true;
** Also note that you need at least two points in your array or you get access violation again, so you need to check for this and you have the same problem in "countPointsAboveThreshold" function that you need to fix too.
Please check for syntax and typos ;)
But any way I strongly recommend following two last post recommendations too.
精彩评论