Проблема с моим динамическим c массивом - Тема 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0) - PullRequest
1 голос
/ 03 апреля 2020

У меня проблема при отладке: Xcode выдает:

Поток 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0)

I думаю, это проблема с моим динамическим c массивом ...

Моя задача - вычислить периметр многоугольника с точками.

Итак, моя программа получает точки (x и y) чтобы заполнить массив Point s, я создал другой массив, distance, который заполняю всеми расстояниями, а затем могу вычислить периметр.

Я не знаю, очень ли это ясно, но я новичок в C ++.

#include <iostream>
#include "Point.h"
#include "Polygone.h"
using namespace std;
int main() {
    int numberSide;
    int x,y;
    Point* array = nullptr;
    Polygone myPolygone;
    cout<<"enter number of sides:"<<endl;
    cin>>numberSide;
    float* distance=new float[numberSide];
    cout<<"enter points:"<<endl;
    for (int i=0; i<numberSide; i++) {
        cin>>x>>y;
        Point p(x,y);
        array[i]=p;
    }
    for (int i=0; i<numberSide-1; i++) {
        distance[i]=array[i].distance(array[i+1]);
    }
    distance[numberSide]=array[0].distance(array[numberSide]);
    myPolygone.perimeter(distance);
    delete [] distance;

    return 0;
}

1 Ответ

1 голос
/ 03 апреля 2020

Вы фактически никогда не выделяете место для переменной array - вы только объявляете ее и присваиваете ей значение nullptr. Таким образом, когда вы позже попытаетесь выполнить array[i]=p;, вы пытаетесь разыменовать нулевой указатель, что вызывает вашу ошибку EXC_BAD_ACCESS.

Чтобы исправить это, вам нужно выделить массив, как только вы узнаете, какой размер это (то есть, сколько сторон у вашего многоугольника). Вы должны сделать это так же, как вы распределяете массив distance:

    cin>>numberSide;
    float* distance=new float[numberSide];
    Point* array = new Point[numberSide]; // And you should delete the earlier "Point* array = nullptr;` line

Конечно, вам также необходимо освободить память, когда вы закончили с ней:

    delete [] distance;
    delete [] array;
    return 0;

Однако, поскольку вы используете C ++, лучший способ far , чем использование необработанных указателей и оператора new, заключается в использовании контейнера std::vector стандартной библиотеки шаблонов , который занимает заботиться обо всех операциях распределения и освобождения внутри. Вот соответствующие строки 'замены':

#include <vector> // This header defines the `std::vector` container
//...
    cin>>numberSide;
    std::vector<float> distance(numberSide);
    std::vector<Point> array(numberSide); 

Тогда вам не нужны строки delete[], поскольку память векторов будет автоматически освобождена, когда векторы go выйдут из области видимости. , Кроме того, вам не нужно действительно изменять любой другой код, поскольку класс std::vector имеет оператор [], который работает так, как вы этого хотите.

...