BCB 6.0 «поднял класс исключений EAccessViolation с сообщением« Нарушение доступа по адресу »» - PullRequest
0 голосов
/ 17 апреля 2011

Я новичок в C ++.Я написал некоторый код, но когда я запускаю его, всегда есть следующее:

поднял класс исключений EAccessViolation с сообщением «Нарушение доступа по адресу»

я непонимаю это.Хотите помочь мне решить это?Это важно для меня.Действительно, большое спасибо!

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <math.h>
#include <conio.h>
#define k 2
#define minoffset 0.5

using namespace std;

struct Point
{
  double X;
  double Y;
};

vector<Point> dataprocess();
void k_means(vector<Point> points,int N);

double getdistance(Point p1,Point p2)
{   double distance;
    distance=sqrt((p1.X-p2.X)*(p1.X-p2.X)+(p1.Y-p2.Y)*(p1.Y-p2.Y));
    return distance;
}
int getmindis(Point p,Point means[])
{
    int i;
    int c;
    double dis=getdistance(p,means[0]);
    for(i=1;i<k;i++)
    {
       double term=getdistance(p,means[i]);
       if(term<dis)
       {
          c=i;
          dis=term;
       }
    }
    return c;
}



Point getmeans(vector<Point> points)
{
    int i;
    double sumX,sumY;
    Point p;
    int M=points.size();
    for(i=0;i<M;i++)
    {
       sumX=points[i].X;
       sumY=points[i].Y;
    }
    p.X=sumX/M;
    p.Y=sumY/M;
    return p;
}


int main()
{   int N;
    vector<Point> stars;
    stars=dataprocess();
    N=stars.size();
    cout<<"the size is:"<<N<<endl;

    k_means(stars,N);
    getch();
}

vector<Point> dataprocess()
{
   int i;
   int N;
   double x,y;
   vector<Point> points;


   Point p;
   string import_file;

   cout<<"input the filename:"<<endl;
   cin>>import_file;
   ifstream infile(import_file.c_str());

   if(!infile)
   {
      cout<<"read error!"<<endl;
   }

   else
   {
      while(infile>>x>>y)
      {
         p.X=x;
         p.Y=y;
         points.push_back(p);
      }
   }
    N=points.size();
    cout<<"output the file data:"<<endl;
    for(i=0;i<N;i++)
    {
        cout<<"the point"<<i+1<<"is:X="<<points[i].X<<"   Y="<<points[i].Y<<endl;
    }

    return points;
}

void k_means(vector<Point> points,int N)
{
    int i;
    int j;
    int index;
    vector<Point> clusters[k];
    Point means[k];
    Point newmeans[k];
    double d,offset=0;
    bool flag=1;
    cout<<"there will be"<<k<<"clusters,input the original means:"<<endl;

    for(i=0;i<k;i++)
    {
        cout<<"k"<<i+1<<":"<<endl;
        cin>>means[i].X>>means[i].Y;
    }

    while(flag)
    {
        for(i=0;i<N;i++)
        {
            index=getmindis(points[i],means);
            clusters[index].push_back(points[i]);
        }

        for(j=0;j<k;j++)
        {
            newmeans[j]=getmeans(clusters[j]);
            offset=getdistance(newmeans[j],means[j]);
        }

        if(offset>d)
        {
            d=offset;
        }
        flag=(minoffset<d)?true:false;
        for(i=0;i<k;i++)
        {
            means[i]=newmeans[i];
            clusters[i].clear();
        }
    }

    for(i=0;i<k;i++)
    {
     cout<<"N"<<i+1<<"="<<clusters[i].size()<<endl;
     cout<<"the center of k"<<i+1<<"is:"<<means[i].X<<"  "<<means[i].Y<< endl;
    }
}

1 Ответ

1 голос
/ 18 апреля 2011

У вас наверняка есть ошибки в вашем коде. Трудно иметь дело с кодом без входных данных, который вызвал ошибку, но давайте попробуем:

  • Во-первых, давайте посмотрим на функцию Point getmeans(vector<Point> points)

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

смотри здесь - int M=points.size()

и здесь - for(i=0;i<M;i++) { sumX=points[i].X; sumY=points[i].Y; }

если ваш кластер пуст, чем M будет равен нулю, и ваш цикл будет повторяться 2 ^ 31 раз (до 32-разрядного целочисленного переполнения), и каждый раз вы будете пытаться прочитать значения несуществующих векторных элементов

Итак, вы должны проверить, не является ли ваш вектор не пустым, перед запуском цикла основной функции, и вы должны решить, какие средние значения следует назначить для нулевого кластера (может быть, вам нужен дополнительный флаг для пустого кластера, который будет проверен перед имея в виду средние значения кластера)

  • Затем рассмотрим функцию int getmindis(Point p,Point means[]), а также место, где мы ее называем: index=getmindis(points[i],means); clusters[index].push_back(points[i]);

Эта функция указывает на кластеры. номер кластера определяется переменной c. Если входная точка не подходит ни к одному кластеру, функция вернет неинициализированную переменную (содержащую любое возможное значение), которая. затем используется как векторный индекс несуществующего элемента - возможное нарушение прав доступа

Вы, вероятно, должны инициализировать c в ноль в объявлении

Сообщите нам, когда вы будете готовы к ошибкам, описанным выше, а также покажите нам пример входного файла (тот, который вызывает ошибки, если все наборы данных вызывают ошибки, покажите нам самый маленький файл)

...