Указатели на указатели на указатели (ошибка: выражение должно иметь тип classtype) - PullRequest
0 голосов
/ 09 сентября 2011

У меня проблемы с многослойными указателями. В основном я читаю местоположения точек из файла и использую их для отображения полилиний.

Я пытаюсь создать динамически распределенную структуру данных, которая будет меняться в зависимости от информации, содержащейся в файле.

Каждый файл имеет такую ​​структуру.

29 // number of polylines in the whole file
3 // first polyline, number of points in it
32 435 // first coordinate where x = 32 and y = 435
15 200
100 355
10  // second polyline, number of points in it
245 35
330 400

и т. Д.

Я создал структуру с координатами x и y для хранения координат для каждой точки

struct coordinates{
  int x;
  int y;
};

Я хочу создать такую ​​структуру данных, как эта ...

Pointer --> array w/ num of polys
             |      |      |
             |      |      |
             v      v      v
           poly0   poly1  poly2       // arrays with coordinate structs
            x1,y1   x1,y1  x1,y1
            x2,y2   x2,y2  x2,y2
            x3,y3   x3,y3  x3,y3

Вот как выглядит мой код

coordinates *** dinoPoints;

struct coordinates{
      int x;
      int y;
 };

void myInit(void){...} // just has initialization stuff for the draw window

void loadDino (char * fileName)
{
  fstream inStream;
  inStream.open(fileName, ios ::in); // open the file
  if(inStream.fail())
  return;

  GLint numpolys, numlines; // these are just regular ints

  inStream >> numpolys; //reads in number of polys

  //dynamically allocates the number of polys in file to datastructure
  dinoPoints = new coordinates**[numpolys]; 

  for(int j = 0; j < numpolys; j++){  // read each polyline

      inStream >> numlines;  // read in number of lines in polyline

      dinoPoints[j] = new coordinates*[numlines];

      for (int i = 0; i < numlines; i++){  // allocate each set of coords
          dinoPoints[j][i] = new coordinates;

          // read in specific point coordinates
          inStream >> dinoPoints[j][i].x >> dinoPoints[j][i].y;
      }
   }        

   inStream.close();
}

void myDisplay(void)
{
    drawDino();   // draws the dinosaur on the screen
}

//still writing this function. Calls myDisplay through glutDisplayFunc()
// and also calls loadDino with filename passed as a parameter

void main(int argc, char **argv){...}

По какой-то причине он выдает мне сообщение "выражение должно иметь тип classtype"

inStream >> dinoPoints [j] [i] .x >> dinoPoints [j] [i] .y;

Также обычно в среде IDE (Visual Studios 2010) отображаются различные элементы структуры данных после ввода периода, но после ввода «dinoPoints [j] [i].» Он не отображается ни с какими содержащимися элементами выбрать из, что означает, что он даже не знает, о чем я говорю в отношении dinoPoints [j] [i]

Кто-нибудь знает, что я делаю не так? Я чувствую, что что-то упускаю из-за того, как работают многоуровневые указатели, но я точно не знаю, что именно.

Ответы [ 4 ]

3 голосов
/ 09 сентября 2011

У вас есть трехслойный указатель. Вам нужно три разыменования там. У вас есть только два с dinoPoints[j][i] - результатом этого выражения является указатель .

Не говоря уже об ужасной ненадежности того, что вы делаете. Для этого используйте vector<vector<vector<coordinates>>> - это безопаснее и проще для понимания.

1 голос
/ 09 сентября 2011

Вы используете массив массивов указателей для координат здесь (3 уровня), но достаточно массива массивов координат (2 уровня).

Вместо этого:

//dynamically allocates the number of polys in file to datastructure
dinoPoints = new coordinates**[numpolys];

for(int j = 0; j < numpolys; j++){  // read each polyline

    inStream >> numlines;  // read in number of lines in polyline

    dinoPoints[j] = new coordinates*[numlines]; // make an array of pointers
    for (int i = 0; i < numlines; i++){  // allocate each set of coords
        dinoPoints[j][i] = new coordinates;

        // read in specific point coordinates
        inStream >> dinoPoints[j][i].x >> dinoPoints[j][i].y;
    }
}

Просто выполните:

// ** At the beginning of the file **
coordinates **dinoPoints;

// ** Inside the loadDino function **
//dynamically allocates the number of polys in file to datastructure
dinoPoints = new coordinates*[numpolys];

for(int j = 0; j < numpolys; j++){  // read each polyline

    inStream >> numlines;  // read in number of lines in polyline

    dinoPoints[j] = new coordinates[numlines]; // make an array of coordinates
    for (int i = 0; i < numlines; i++) {  // allocate each set of coords
        // read in specific point coordinates
        inStream >> dinoPoints[j][i].x >> dinoPoints[j][i].y;
    }
}

В качестве альтернативы, если вы хотите придерживаться своей исходной структуры данных, просто измените строку, для которой сообщалось об ошибке, на

inStream >> dinoPoints[j][i]->x >> dinoPoints[j][i]->y;
1 голос
/ 09 сентября 2011

Ваша структура данных на самом деле представляется 2D-массивом, а не 3D-массивом. Таким образом, чтобы отразить структуру данных, которую вы описываете, а не тройной указатель для вашего массива, вам нужен только двойной указатель или coordinate**. Это потому, что ваша переменная coordinate должна указывать только на массив указателей, каждый из которых указывает на массив координат, представляющих ваши полигоны. Из того, что я вижу, нет типа «полигон», а вы просто представляете массив координат в виде многоугольника. Таким образом, это только двумерный массив, и ваша переменная dinoPoints должна указывать только на двумерный массив, делая его указателем на указатель (где второй указатель указывает на динамический массив), а не тройной указатель.

Чтобы правильно распределить это, вы должны сделать следующее:

шаг 1) изменить

dinoPoints = new coordinates**[numpolys];

до

dinoPoints = new coordinates*[numpolys];

потому что вам нужен только массив указателей, каждый из которых будет указывать на массив coordinates.

шаг 2) изменить

dinoPoints[j] = new coordinates*[numlines];

до

dinoPoints[j] = new coordinates[numlines];

Теперь, когда вы звоните inStream >> dinoPoints[j][i].x >> dinoPoints[j][i].y;, он должен работать правильно.

Вам потребуется только тип coordinate***, если вы попытаетесь передать dinoPoints в качестве ссылки на функцию, где вы каким-то образом захотите изменить то, на что указывает dinoPoints, и разрешить любую другую функцию, используя dinoPoints чтобы увидеть изменения ... но в данном случае это глобальная переменная, так что в этом нет необходимости ...

0 голосов
/ 09 сентября 2011

Ваши dinoPoints - это указатель на указатель на указатель, вам нужно 3 индекса для доступа к координате, а не 2.

Вы находитесь в C ++, так почему бы вам не использовать vector или boost :: multiarray.

...