访问违规阅读位置

时间:2011-08-21 05:21:53

标签: c++ exception loops dynamic heap

我有VC ++的问题,简单地说,我讨厌哈哈。我的代码似乎在我的Mac上运行正常,但是当我尝试在VC ++中运行它时,我在调试中遇到了这个错误:

  

Windows在Assignment1-FINAL.exe中触发了断点。

     

这可能是由于堆的损坏,这表明存在错误   Assignment1-FINAL.exe或它已加载的任何DLL。

     

这也可能是由于用户在按下F12时   Assignment1-FINAL.exe具有焦点。

我知道一个事实我没有按F12,所以我不知道为什么我会得到这个...然后,当我尝试在发布模式下运行时,我得到了这个:

  

Assignment1-FINAL.exe中0x00401473处的未处理异常:   0xC0000005:访问冲突读取位置0x00347015。

这是我正在使用的代码:

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;
}

这是主要功能:

    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;

3 个答案:

答案 0 :(得分:2)

初学者的想法: 断言在哪里?您在countPointsAboveThreshold()中访问Points *作为数组,但不进行任何边界检查以确保您没有通过数组的结束。这将是我检查内存踩踏动作的第一个区域。此外,直接指针调用非常C.哎呀,您不是在任何数组调用中检查边界。危险...

新的长度为0的数组可能安全也可能不安全。我会小心的。

当我在声明中看到[i - 1]时我会感到紧张。在i == 0

非常容易阅读垃圾

i,j,k循环与quadrouple嵌套ifs混合继续和休息?没有。重新思考逻辑。这是方式,太复杂了。

您提前返回,并在pointsToCalculate []中分配了内存。内存泄漏。

我可以建议将你的最后一个功能分成多个部分以简化逻辑吗?

男人,我讨厌K&amp; R风格的支架。你的选择 - 不是在这里开始那场圣战:P

除此之外,我会继续我的第一个建议,并确保你的结束布尔总是设置,并且你不会超出界限。如前所述,stl :: vector和一些引用(最好是const)是你的朋友。

答案 1 :(得分:0)

你把它作为C ++发布,但它似乎只使用了很少的C ++实际上是什么:对象。这段代码更像是C。

只是一些注释:

  1. 使用C ++,您不需要执行typedef struct {...} point,而struct point {...}执行您要执行的操作。
  2. 如果您使用stl::vector而不是c-array,那么您的循环将变得更加简单,您将不再需要您的函数totalPoints()。您还可以从endpoint
  3. 中删除成员变量pointValues
  4. 您正在堆上而不是在堆栈上创建大量变量,这是没有充分理由的。使用stl::vector(或其他标准容器),本地变量和引用,您可以大大简化内存管理并避免出现这些奇怪的崩溃。
  5. 我会深入研究一下你的代码,看看我是否可以给你一些更具体的指导,但你真的应该进一步阅读C ++提供的C语言。我要看看cplusplus.comC++ FAQ。还有一些出色的图书建议here

答案 2 :(得分:0)

这部分代码听起来很奇怪:

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 - 1)来填充pointsToCalculate!

我会重写这个部分:

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;

**另请注意,您的阵列中至少需要两个点,否则会再次出现访问冲突,因此您需要检查此问题,并且您在“countPointsAboveThreshold”函数中遇到同样的问题,您也需要修复它。 / p>

请检查语法和拼写错误;)

但是我强烈建议你遵循两篇最后的帖子推荐。