Доступ к информации о нарушении - PullRequest
0 голосов
/ 21 августа 2011

У меня проблема с VC ++, просто, я ненавижу это, ха-ха.Кажется, мой код работает нормально на моем Mac, но когда я пытаюсь запустить его в VC ++, я получаю эту ошибку при отладке:

Windows сработала точку останова в Assignment1-FINAL.exe.

Это может быть связано с повреждением кучи, что указывает на ошибку в Assignment1-FINAL.exe или любой из загруженных им DLL-библиотек.

Это также может быть вызвано нажатием пользователемF12, в то время как Assignment1-FINAL.exe имеет фокус.

Я точно знаю, что не нажимал F12, поэтому я не уверен, почему я получаю это ... Затем, когда я пытаюсь запуститьв режиме Release я получаю следующее:

Необработанное исключение по адресу 0x00401473 в Assignment1-FINAL.exe: 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 ]

2 голосов
/ 21 августа 2011

Начальные мысли: где утверждения?Ваши точки доступа * в countPointsAboveThreshold () в виде массива, но вообще не проверяют границы, чтобы убедиться, что вы не прошли конец массива.Это было бы моей первой областью проверки действия памяти.Кроме того, вызовы с прямым указателем - это очень C. Черт, вы не проверяете границы ни в одном из вызовов массива.Опасный ...

Новые массивы длины 0 могут быть или не быть безопасными.Я был бы осторожен с этим.

Черт, каждый раз, когда я вижу [i - 1] в заявлении, я нервничаю.Очень легко читать мусор при i == 0

циклах i, j, k с вложенными четырьмя группами if, смешанными с continue и break?Переосмыслите эту логику.Это, кстати, СЛИШКОМ слишком сложно.

Вы рано возвращаетесь с памятью, выделенной в pointsToCalculate [].Там утечка памяти.

Могу ли я предложить разбить вашу последнюю функцию на несколько частей, чтобы упростить логику?

Человек, которого я ненавижу в стиле K & R.Хотя ваш выбор - не здесь, чтобы начать эту священную войну: P

Помимо этого, я бы пошел с моим первым предложением и убедился, что ваш конечный бул установлен всегда и что вы не выходите за пределы,Как уже предлагалось ранее, stl :: vector и несколько ссылок (предпочтительно const) - ваши друзья здесь.

0 голосов
/ 23 августа 2011

Эта часть вашего кода звучит для меня странно:

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», которую вам тоже нужно исправить.

Пожалуйста, проверьте синтаксис и опечатки;)

Но в любом случае я настоятельно рекомендую следовать двум последним постамрекомендации тоже.

0 голосов
/ 21 августа 2011

Вы опубликовали это как C ++, но, похоже, он использует очень мало того, что на самом деле есть в C ++: объекты. Этот код читается гораздо больше как C.

Только некоторые заметки:

  1. С C ++ вам не нужно делать typedef struct {...} point, выполнение struct point {...} делает то, что вы пытаетесь сделать.
  2. Если вы используете stl :: vector вместо c-массива, тогда ваши циклы станут намного проще, и вам не понадобится ваша функция totalPoints(). Вы также можете избавиться от переменной-члена end из point и pointValues
  3. Вы создаете много переменных в куче, а не в стеке без веской причины. С stl::vector (или другими стандартными контейнерами), локальными переменными и ссылками вы можете значительно упростить управление памятью и избежать странных сбоев, подобных этим.

Я посмотрю на ваш код глубже и посмотрим, смогу ли я дать вам более конкретные рекомендации, но вам действительно стоит немного углубиться в изучение того, что C ++ предоставляет над C. Я бы взглянул на cplusplus .com и C ++ FAQ . Есть также несколько прекрасных предложений книг здесь .

...