Форум программистов, компьютерный форум CyberForum.ru

не пойму из-за чего Access violation - C++

Восстановить пароль Регистрация
 
dwa83
0 / 0 / 0
Регистрация: 14.06.2013
Сообщений: 13
24.06.2013, 03:31     не пойму из-за чего Access violation #1
При запуске проги происходит Access violation. Причём ранее проект был написан в bcb6, затем ради эксперимента(и возможного переезда) перенесён в vc++ 6. И там, и здесь всё работало в норме. При переезде обратно на борланда опять же всё компилится, но происходит access violation при new. Понять не могу почему.

C++
1
2
3
4
5
6
7
// выделение памяти под полигоны
void Mesh::CreatePolygons(int count)
{
  this->p_count=count;
  this->DelPolygons();
  this->polygon= new Polygon3d[count];  // здесь происходит ошибка
}
до этого в основном модуле происходит объявление

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
StaticModel model;      // статичная модель
 
StaticModel представляет собой
struct StaticModel
{
  float rotx;
  float roty;
  float rotz;
 
  unsigned short m_count;       // количество сеток
  Mesh *mesh;                   // массив сеток
  TextureLibrary *texlib;       // указатель на библиотеку текстур
  Shader *shader;
  Vector3f work;
 
  void CreateMeshes(int count); // выделение памяти для отдельных сеток модели
  unsigned int FindChunk(ifstream& ifs, unsigned short id, bool isParent=true);
  bool Load3DS(char *p_filename);
  void Render();
};
CreatePolygons вызывается из

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
bool StaticModel::Load3DS(char *p_filename)
{
    int p;
 
    FILE *file = fopen(p_filename, "rb");         
    if (file==NULL) 
    {
      MsgLog(p_filename);   
      MsgLog("Файл модели не найден");
      return false; 
    }   
    
    unsigned short mcount;
 
    fread(&mcount,1,2,file);  // считали количество сеток
    CreateMeshes(mcount);       // создаём массив сеток
    for (int i=0; i<mcount; i++)
    {
      bool smooth;
      unsigned short vc,tc,pc;
 
      fread(&smooth,1,1,file);  // считаем сглаживание
      fread(&vc,1,2,file);  // считаем количество вершин
      mesh[i].CreateVertices(vc); // создаём массив вершин
      fread(&tc,1,2,file);  // считываем количество текстурных координат
      mesh[i].CreateTexcoords(tc);// создаём массив текстурных координат
      fread(&pc,1,2,file);  // считываем количество полигонов
      mesh[i].CreatePolygons(pc); // <- создаём массив полигонов ->> переходя отсюда и происходит ошибка
 
      // считываем все вершины
      for (int v=0; v<vc; v++)
      {
        fread(&mesh[i].vertex[v].x,1,4,file);
        fread(&mesh[i].vertex[v].z,1,4,file);
        fread(&mesh[i].vertex[v].y,1,4,file);
        mesh[i].vertex[v].z=-mesh[i].vertex[v].z;
      }
 
      // считываем все текстурные координаты
      for (int t=0; t<tc; t++)
      {
        fread(&mesh[i].texcoord[t].x,1,4,file);
        fread(&mesh[i].texcoord[t].y,1,4,file);
      }
 
      // считываем все номера вершин в полигонах
      for (p=0; p<pc; p++)
      {
        fread(&mesh[i].polygon[p].nom_vertex[0],1,2,file);
        fread(&mesh[i].polygon[p].nom_vertex[1],1,2,file);
        fread(&mesh[i].polygon[p].nom_vertex[2],1,2,file);
      }
 
      // считываем все номера текстурных координат для полигонов
      for (p=0; p<pc; p++)
      {
        fread(&mesh[i].polygon[p].nom_texcoord[0],1,2,file);
        fread(&mesh[i].polygon[p].nom_texcoord[1],1,2,file);
        fread(&mesh[i].polygon[p].nom_texcoord[2],1,2,file);
      }
 
      for (p=0; p<pc; p++)
      {
        // расчёт тангент-оси
        Vector3f p1 = mesh[i].vertex[mesh[i].polygon[p].nom_vertex[0]];
        Vector3f p2 = mesh[i].vertex[mesh[i].polygon[p].nom_vertex[1]];
        Vector3f p3 = mesh[i].vertex[mesh[i].polygon[p].nom_vertex[2]];
 
        Texcoord t1 = mesh[i].texcoord[mesh[i].polygon[p].nom_texcoord[0]];
        Texcoord t2 = mesh[i].texcoord[mesh[i].polygon[p].nom_texcoord[1]];
        Texcoord t3 = mesh[i].texcoord[mesh[i].polygon[p].nom_texcoord[2]];
 
        mesh[i].polygon[p].tangent=((t3.y-t1.y)*(p2-p1)-(t2.y-t1.y)*(p3-p1))/((t2.x-t1.x)*(t3.y-t1.y)-(t3.x-t1.x)*(t2.y-t1.y));
 
        mesh[i].polygon[p].tangent.normalise();
      }
 
      // имя файла текстуры
      char tname[255]={0};
      int cnt=0;
      do
      {
        fread(&tname[cnt],1,1,file);
        cnt++;
      }
      while (tname[cnt-1]!=0);
 
      // загрузка текстуры и карты нормалей
      mesh[i].texID=texlib->Load(tname);
      char nm_name[255] = {0};
      strcat(nm_name, "nm_");
      strcat(nm_name, tname);
      mesh[i].normmapID=texlib->Load(nm_name);
      
      // расчёт нормалей
      if (smooth)
      mesh[i].CalculateSmoothNormals();
      else
      mesh[i].CalculateNormals();
      
    }
 
    fclose(file);
    return true;
}
Не пойму что не так.. Если вручную count заменить на 1 или 20, то проходит нормально, но при следующем new в другой функции опять ошибка доступа..
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.06.2013, 03:31     не пойму из-за чего Access violation
Посмотрите здесь:

C++ почему выдает access violation?
C++ Access violation
Ошибка Access Violation C++
C++ Crash (access violation)
C++ access violation at address
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.06.2013, 14:47     не пойму из-за чего Access violation #2
DelPolygons() как реализован? Если удалять ещё нечего?

Добавлено через 3 минуты
Причина ошибки может и не в этом, но, при чтении из файла (да и в других случаях), размер типа данных (unsigned short) лучше задавать через sizeof(), а не вручную.
dwa83
0 / 0 / 0
Регистрация: 14.06.2013
Сообщений: 13
24.06.2013, 16:05  [ТС]     не пойму из-за чего Access violation #3
Цитата Сообщение от alsav22 Посмотреть сообщение
DelPolygons() как реализован? Если удалять ещё нечего?
Удаление происходит так, вроде всё правильно, ошибка получается именно при new
Код
// удаление полигонов
void Mesh::DelPolygons()
{
  if (this->polygon!=NULL) delete []this->polygon; // удалим если уже выделено
  this->polygon=NULL;
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.06.2013, 16:15     не пойму из-за чего Access violation #4
В отладчике смотрели?
C++
1
this->polygon= new Polygon3d[count];
count здесь нормальный?
dwa83
0 / 0 / 0
Регистрация: 14.06.2013
Сообщений: 13
24.06.2013, 16:45  [ТС]     не пойму из-за чего Access violation #5
Вроде нормальный. Ставил точку останова - count = 576 (полигонов). Пробовал вручную указывать значения, если указывать маленькие типа 20-50, то выделяется, иначе access violation. Да и если проходит, то уже в другом модуле в строчке
TextureElement *newtex = new TextureElement; //
опять такая же ерунда

Добавлено через 14 минут
Вот на всякий случай весь модуль, может кто разберётся и подскажет в чём ошибка. Странно, что раньше всё работало нормально..
Кликните здесь для просмотра всего текста
h
Код
#include "Shaders.h"
#include "Textures/TextureLibrary.h"

// полигон
struct Polygon3d
{
  unsigned short nom_vertex[3];     // номера вершин
  unsigned short nom_texcoord[3];   // номера текстурных координат
  Vector3f normal[3];               // нормали
  Vector3f tangent;
};

// элемент модели
struct Mesh
{
  unsigned int texID;           // идентификатор текстуры меша
  unsigned int normmapID;       // id карты нормалей
  bool SmoothNormal;            // сглаженные ли нормали
  unsigned short v_count;       // количество вершин
  unsigned short p_count;       // количество полигонов
  unsigned short t_count;       // количество текстурных координат
  unsigned short n_count;       // количество нормалей
  Vector3f *vertex;  // динамический массив вершин
  Vector3f *normal;  // динамический массив нормалей
  Texcoord *texcoord;// массив текстурных координат
  Polygon3d *polygon;// динамический массив полигонов

  void CalculateNormals();
  void CalculateSmoothNormals();

  void CreateVertices(int count);  // выделение памяти для вершин
  void CreateTexcoords(int count); // выделение памяти для текстурных координат
  void CreateNormals(int count);   // выделение памяти для нормалей
  void CreatePolygons(int count);  // выделение памяти для полигонов

  void DelVertices();
  void DelTexcoords();
  void DelNormals();
  void DelPolygons();
};

struct StaticModel
{
  float rotx;
  float roty;
  float rotz;

  unsigned short m_count;       // количество сеток
  Mesh *mesh;                   // массив сеток
  TextureLibrary *texlib;       // указатель на библиотеку текстур
  Shader *shader;
  Vector3f work;

  void CreateMeshes(int count); // выделение памяти для отдельных обьектов модели
  unsigned int FindChunk(ifstream& ifs, unsigned short id, bool isParent=true);
  bool Load3DS(char *p_filename);
  void Render();
};

Кликните здесь для просмотра всего текста
cpp
Код
#include <windows.h>
#include <GL\gl.h>
#include <GL\glu.h>
#include <fstream.h>

#include "Math3d.h"
#include "Model3d.h"
#include "ErrorLog.h"

// удаление вершин
void Mesh::DelVertices()
{
  if (this->vertex!=NULL) delete []this->vertex; // удалим если уже выделено
  this->vertex=NULL;
}

// удаление текстурных координат
void Mesh::DelTexcoords()
{
  if (this->texcoord!=NULL) delete []this->texcoord; // удалим если уже выделено
  this->texcoord=NULL;
}

// удаление нормалей
void Mesh::DelNormals()
{
  if (this->normal!=NULL) delete []this->normal; // удалим если уже выделено
  this->normal=NULL;
}

// удаление полигонов
void Mesh::DelPolygons()
{
  if (this->polygon!=NULL) delete []this->polygon; // удалим если уже выделено
  this->polygon=NULL;
}

// выделение памяти под массив вершин
void Mesh::CreateVertices(int count)
{
  this->v_count=count;
  this->DelVertices();
  this->vertex= new Vector3f[count];
}

// выделение памяти под массив текстурных координат
void Mesh::CreateTexcoords(int count)
{
  this->t_count=count;
  this->DelTexcoords();
  this->texcoord= new Texcoord[count];
}

// выделение памяти под массив текстурных координат
void Mesh::CreateNormals(int count)
{
  this->n_count=count;
  this->DelNormals();
  this->normal= new Vector3f[count];
}

// выделение памяти под массив полигонов
void Mesh::CreatePolygons(int count)
{
  this->p_count=count;
  this->DelPolygons();
  this->polygon= new Polygon3d[count];
}


// расчёт нормалей
void Mesh::CalculateNormals()
{
  for (int i=0; i<p_count; i++)
  {
    Vector3f a=vertex[polygon[i].nom_vertex[0]]-vertex[polygon[i].nom_vertex[1]];
    Vector3f b=vertex[polygon[i].nom_vertex[0]]-vertex[polygon[i].nom_vertex[2]];
    Vector3f norm=cross(a,b);
    norm.normalise();
    polygon[i].normal[0]=norm;
    polygon[i].normal[1]=norm;
    polygon[i].normal[2]=norm;
  }
}

// расчёт сглаженных нормалей
void Mesh::CalculateSmoothNormals()
{
  int p;

  CalculateNormals();

  Vector3f *nrm=new Vector3f[p_count]; // временный массив нормалей полигона
  for (p=0; p<p_count; p++)
  nrm[p]=polygon[p].normal[0];

  for (int i=0; i<v_count; i++)
  {
    Vector3f vnorm;
    for (p=0; p<p_count; p++)
    {
      // если вершина входит в полигон..
      if ((polygon[p].nom_vertex[0]==i)||
          (polygon[p].nom_vertex[1]==i)||
          (polygon[p].nom_vertex[2]==i))
      vnorm+=nrm[p]; // прибавляем нормаль полигона
    }
    vnorm.normalise(); // нормализуем

    // проставим нормаль во всех полигонах, использующих эту вершину
    for (p=0; p<p_count; p++)
    {
      if (polygon[p].nom_vertex[0]==i) polygon[p].normal[0]=vnorm;
      if (polygon[p].nom_vertex[1]==i) polygon[p].normal[1]=vnorm;
      if (polygon[p].nom_vertex[2]==i) polygon[p].normal[2]=vnorm;
    }
  }

  delete []nrm;
}


// выделение памяти под массив сеток
void StaticModel::CreateMeshes(int count)
{
  this->m_count=count;
  if (this->mesh!=NULL) // если массив сеток создан
  {
    for (int i=0; i<m_count; i++)
    {
      this->mesh[i].DelNormals(); //удалим нормали
      this->mesh[i].DelVertices(); //удалим вершины
      this->mesh[i].DelTexcoords(); //удалим текстурные коорды
      this->mesh[i].DelPolygons(); //удалим полигоны
    }
    delete []this->mesh;
  }
  this->mesh= new Mesh[count];

  for (int i=0; i<m_count; i++)
  {
    this->mesh[i].vertex=NULL;
    this->mesh[i].normal=NULL;
    this->mesh[i].texcoord=NULL;
    this->mesh[i].polygon=NULL;
  }
}





bool StaticModel::Load3DS(char *p_filename)
{
    int p;

	FILE *file = fopen(p_filename, "rb");         
	if (file==NULL) 
	{
	  MsgLog(p_filename);	
      MsgLog("Файл модели не найден");
	  return false;	
	}	
	
    unsigned short mcount;

	fread(&mcount,1,2,file);  // считали количество сеток
    CreateMeshes(mcount);       // создаём массив сеток
    for (int i=0; i<mcount; i++)
    {
      bool smooth;
      unsigned short vc,tc,pc;

      fread(&smooth,1,1,file);  // считаем сглаживание
      fread(&vc,1,2,file);  // считаем количество вершин
      mesh[i].CreateVertices(vc); // создаём массив вершин
      fread(&tc,1,2,file);  // считаем количество текстурных координат
      mesh[i].CreateTexcoords(tc);// создаём массив текстурных координат
      fread(&pc,1,2,file);  // считаем количество полигонов
      mesh[i].CreatePolygons(pc); // создаём массив полигонов

      // считаем все вершины
      for (int v=0; v<vc; v++)
      {
        fread(&mesh[i].vertex[v].x,1,4,file);
	    fread(&mesh[i].vertex[v].z,1,4,file);
	    fread(&mesh[i].vertex[v].y,1,4,file);
        mesh[i].vertex[v].z=-mesh[i].vertex[v].z;
	  }

      // считаем все текстурные координаты
      for (int t=0; t<tc; t++)
      {
        fread(&mesh[i].texcoord[t].x,1,4,file);
	    fread(&mesh[i].texcoord[t].y,1,4,file);
	  }

      // считаем все номера вершин в полигонах
      for (p=0; p<pc; p++)
      {
        fread(&mesh[i].polygon[p].nom_vertex[0],1,2,file);
	    fread(&mesh[i].polygon[p].nom_vertex[1],1,2,file);
	    fread(&mesh[i].polygon[p].nom_vertex[2],1,2,file);
      }

      // считаем все номера текстурных координат для полигонов
      for (p=0; p<pc; p++)
      {
        fread(&mesh[i].polygon[p].nom_texcoord[0],1,2,file);
	    fread(&mesh[i].polygon[p].nom_texcoord[1],1,2,file);
	    fread(&mesh[i].polygon[p].nom_texcoord[2],1,2,file);
      }

      for (p=0; p<pc; p++)
      {
        // расчёт тангент-оси
        Vector3f p1 = mesh[i].vertex[mesh[i].polygon[p].nom_vertex[0]];
        Vector3f p2 = mesh[i].vertex[mesh[i].polygon[p].nom_vertex[1]];
        Vector3f p3 = mesh[i].vertex[mesh[i].polygon[p].nom_vertex[2]];

        Texcoord t1 = mesh[i].texcoord[mesh[i].polygon[p].nom_texcoord[0]];
        Texcoord t2 = mesh[i].texcoord[mesh[i].polygon[p].nom_texcoord[1]];
        Texcoord t3 = mesh[i].texcoord[mesh[i].polygon[p].nom_texcoord[2]];

        mesh[i].polygon[p].tangent=((t3.y-t1.y)*(p2-p1)-(t2.y-t1.y)*(p3-p1))/((t2.x-t1.x)*(t3.y-t1.y)-(t3.x-t1.x)*(t2.y-t1.y));

        mesh[i].polygon[p].tangent.normalise();
      }

      // имя файла текстуры
      char tname[255]={0};
      int cnt=0;
      do
      {
        fread(&tname[cnt],1,1,file);
        cnt++;
      }
      while (tname[cnt-1]!=0);

      // загрузка текстуры и карты нормалей
      mesh[i].texID=texlib->Load(tname);
	  char nm_name[255] = {0};
      strcat(nm_name, "nm_");
      strcat(nm_name, tname);
      mesh[i].normmapID=texlib->Load(nm_name);
      
      // расчёт нормалей
      if (smooth)
      mesh[i].CalculateSmoothNormals();
      else
      mesh[i].CalculateNormals();
      
	}

	fclose(file);
    return true;
}

void StaticModel::Render()
{

  for (int m=0; m<m_count; m++)
  {
    shader->SetTexture(0,mesh[m].texID,"TextureSampler");
    shader->SetTexture(1,mesh[m].normmapID,"NormalSampler");

    glBegin(GL_TRIANGLES);
    for (int p=0; p<mesh[m].p_count; p++)
    {
      // передадим в шейдер значения осей
      GLuint uni = shader->GetUniformLocation("Tangent");
      shader->setUniformf(uni, mesh[m].polygon[p].tangent.x, mesh[m].polygon[p].tangent.y, mesh[m].polygon[p].tangent.z);


      for (int v=0; v<3; v++)
      {

        glNormal3f(mesh[m].polygon[p].normal[v].x,
                   mesh[m].polygon[p].normal[v].y,
                   mesh[m].polygon[p].normal[v].z);
        glTexCoord2f(mesh[m].texcoord[mesh[m].polygon[p].nom_texcoord[v]].x,
                     mesh[m].texcoord[mesh[m].polygon[p].nom_texcoord[v]].y);
        glVertex3f(mesh[m].vertex[mesh[m].polygon[p].nom_vertex[v]].x,
                   mesh[m].vertex[mesh[m].polygon[p].nom_vertex[v]].y,
                   mesh[m].vertex[mesh[m].polygon[p].nom_vertex[v]].z);

      }
    }
    glEnd();
  }



}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.06.2013, 17:37     не пойму из-за чего Access violation #6
Удалил.
dwa83
0 / 0 / 0
Регистрация: 14.06.2013
Сообщений: 13
26.06.2013, 09:54  [ТС]     не пойму из-за чего Access violation #7
Вобщем всё странным образом заработало после скачки с бубном. Скорее всего действительно файл неправильно считывался, и некоторые массивы создавались как new[0], потому ошибка доступа была. Теперь интересно почему например fread(&с, 1, 100, file); работает не так, как fread(&с, 100, 1, file); Ведь в первом случае 100 раз считывает по 1 байту, а во втором 1 раз пачку в сто байт? И ещё такой вопрос, чем пользоваться "правильнее", FILE или fstream и почему?
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
26.06.2013, 10:18     не пойму из-за чего Access violation #8
Цитата Сообщение от dwa83 Посмотреть сообщение
Теперь интересно почему например fread(&с, 1, 100, file); работает не так, как fread(&с, 100, 1, file)
А в чем проявляется "не так"?
Цитата Сообщение от dwa83 Посмотреть сообщение
чем пользоваться "правильнее", FILE или fstream и почему?
FILE - это c-style, fstream - с++
dwa83
0 / 0 / 0
Регистрация: 14.06.2013
Сообщений: 13
26.06.2013, 10:22  [ТС]     не пойму из-за чего Access violation #9
Цитата Сообщение от Tulosba Посмотреть сообщение
А в чем проявляется "не так"?
Не правильно считывалось, поменял местами размер считываемого блока и количество блоков - всё стало считываться правильно(именно то количество байт, которое нужно), странности какие-то.

То-есть принципиальной разницы, как я понял, нету, и можно и FILE и fstream.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
26.06.2013, 10:56     не пойму из-за чего Access violation #10
Цитата Сообщение от dwa83 Посмотреть сообщение
странности какие-то
а код возврата fread() проверяли и в том и в другом случаях?
Цитата Сообщение от dwa83 Посмотреть сообщение
и можно и FILE и fstream.
Можно. Но следует придерживаться единого стиля. И я бы рекомендовал fstream (надеюсь не нужно объяснять преимущества ООП подхода перед процедурным).
dwa83
0 / 0 / 0
Регистрация: 14.06.2013
Сообщений: 13
26.06.2013, 11:24  [ТС]     не пойму из-за чего Access violation #11
Цитата Сообщение от Tulosba Посмотреть сообщение
а код возврата fread() проверяли и в том и в другом случаях?
Не проверял, понадеялся зря на безошибочность. Думаю стоит добавить проверку правильности считывания.
А вообще почему первый вариант может вернуть ошибку?(тогда как второй по сути такой же, но считывает без ошибки)
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
26.06.2013, 11:35     не пойму из-за чего Access violation #12
Цитата Сообщение от dwa83 Посмотреть сообщение
А вообще почему первый вариант может вернуть ошибку?
С ходу не скажу. Надо смотреть конкретный код.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.06.2013, 11:37     не пойму из-за чего Access violation
Еще ссылки по теме:

Не пойму чего хочет компилятор C++
Ошибка в коде.не пойму из-за чего C++
access violation reading location C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.06.2013, 11:37     не пойму из-за чего Access violation #13
Цитата Сообщение от dwa83 Посмотреть сообщение
А вообще почему первый вариант может вернуть ошибку?(тогда как второй по сути такой же, но считывает без ошибки)
Вы сначала проверку сделайте, всё может и не так оказаться.
Yandex
Объявления
26.06.2013, 11:37     не пойму из-за чего Access violation
Ответ Создать тему
Опции темы

Текущее время: 18:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru