128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
1

Создание динамических массивов внутри класса: Нарушение прав доступа при чтении "0xbf800000"

10.09.2014, 12:40. Показов 2191. Ответов 19
Метки нет (Все метки)

столкнулся с непонятной для меня бедой. Если код написать внутри главной функции то всё работает. Но если попытаться перенести работу в объект то вылетаю с ошибкой
Необработанное исключение в "0x001d10f1" в "test_stl.exe": 0xC0000005: Нарушение прав доступа при чтении "0xbf800000".
Ошибка возникает, когда пытаюсь обратиться к элементу динамического массива созданного внутри конструктора.
triangles.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#include <share.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
 
class triangles
{
public:
    triangles(char*);
    ~triangles();
    unsigned long get_num();
    float get_coord(int,int,int);
private:
    int fh;
    unsigned long num;
    float **nV;
    float ***tr;
    unsigned short *attr;
    char *name;
protected:
};
triangles.cpp
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
#include "triangles.h"
 
triangles::triangles(char* name)
{
    //присваиваем имя файла(адрес)
    this->name = name;
    //создаем дескриптор файла на чтение
    this->fh = _sopen(this->name, _O_BINARY | _O_RDONLY, _SH_DENYRD);
    //читаем заголовок (он нам не интересен) и если он читается
    if(_read(this->fh, &(this->num), 80*sizeof(char))!=-1)
    {
        //читаем количество треугольников
        _read(this->fh, &(this->num), sizeof(int));
        //создаем массив указателей на вектора нормалей по количеству треугольников
        this->nV = new float*[this->num];
        //создаем массив атрибутов
        this->attr = new unsigned short[this->num];
        //создаем массив указателей на указатели треугольников arr[i][вершины][координаты вершин]
        this->tr = new float**[this->num];
printf("%i \t\n",this->num);
        for(unsigned int i = 0;i<this->num;i++)
        {
            //создаем массив вершин конца вектора нормали
            this->nV[i] = new float[3];
            //создаем массив указателей на вершины треугольников
            this->tr[i] = new float*[3];
            //читаем нормали
            _read(this->fh, &(this->nV[i]), 3*sizeof(float));
//Тут ошибка обращения
//printf("%i) \t %f \t %f \t %f\n", i+1, this->nV[i][0],this->nV[i][1],this->nV[i][2]);
            for(unsigned int j = 0;j<3;j++)
            {
                //создаем массив координат вершин треугольников
                this->tr[i][j] = new float[3];
                //читаем координаты вершин
                _read(this->fh, &(this->tr[i][j]), sizeof(float)*3);
//И тут
//printf("[%i,%i]\t%f \t %f \t %f\n", i+1,j+1, this->tr[i][j][0],this->tr[i][j][1],this->tr[i][j][2]);
            }
            //читаем атрибуты треугольника
            _read(this->fh, &(this->attr[i]), sizeof(unsigned short));
        }
    }
    _close(fh);
};
triangles::~triangles()
{
    delete[] this->attr;
    for(unsigned int i = 0;i<this->num;i++)
        {
            delete[] this->nV[i];
            delete[] this->tr[i][0];
            delete[] this->tr[i][1];
            delete[] this->tr[i][2];
            delete[] this->tr[i];
        }
};
unsigned long triangles::get_num()
{
    return this->num;
};
float triangles::get_coord(int i,int j,int k)
{
//и тут
//  return this->tr[i].tr[j][k];
//  return this->tr[i][j][k];
};
Код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "triangles.h"
#include <conio.h>
#include <exception>
 
int main(int argc,char *argv)
{
    char name[] = "1.stl";
    triangles *tr;
    tr = new triangles(name);
 
    _getch();
    return 0;
}
Немножко о том, что хочу получить:
читаю файл, в котором сначала идет 80 символов заголовка, который мне не нужен (если подскажите как перешагнуть через него буду рад), потом идет число, которое показывает количество структур записанных в файл. И потом энное количество этих структур. Одна структура представляет из себя
float[3]
float[3][3]
unsigned short
Что я делаю:
Я читаю 80 символов, потом количество этих структур, потом создаю динамический массив из элементов этих структур и у меня должны получиться двумерный массив, трёхмерный массив и одномерный массив. Так при обращение к элементам двумерного или трёхмерного массива всё рушится.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.09.2014, 12:40
Ответы с готовыми решениями:

"Нарушение прав доступа при чтении по адресу" при организации класса очереди типа FIFO
Есть класс очереди типа FIFO: class FIFO { private: int* queue; int cols; public:...

Необработанное исключение в "0x775e15de" в "laba3.exe": 0xC0000005: Нарушение прав доступа при чтении "0xfdfdfdf9".
вылезает ошибка Необработанное исключение в &quot;0x775e15de&quot; в &quot;laba3.exe&quot;: 0xC0000005: Нарушение прав...

Необработанное исключение в "0x778e15de" в "dir-3.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000000"
#include &lt;windows.h&gt; #include &lt;d3d9.h&gt; LRESULT __stdcall WndProc(HWND hWnd, UINT msg, WPARAM...

Необработанное исключение в "0x00414558" в "467.exe": 0xC0000005: Нарушение прав доступа при чтении "0xabababbb"
При выполнении этого кода #include &lt;iostream&gt; #include&lt;conio.h&gt; using namespace std; int...

19
54 / 54 / 37
Регистрация: 05.09.2013
Сообщений: 1,864
10.09.2014, 16:30 2
C++
1
_read(this->fh, &(this->nV[i]), 3*sizeof(float));
убрать &. В остальных случаях - аналогично. Нарисуйте ситуацию на листе бумаги и посмотрите, что куда указывает и куда вы пытаетесь записать данные.
1
:)
Эксперт С++
4769 / 3263 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
10.09.2014, 16:49 3
Цитата Сообщение от KokosSPb Посмотреть сообщение
потом создаю динамический массив из элементов этих структур
Учитесь использовать типы из стандартной библиотеки, std::vector в первую очередь. А потом и умные указатели.
На ручном выделении/освобождении памяти далеко не уедешь.
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
10.09.2014, 17:40  [ТС] 4
Цитата Сообщение от FiLF Посмотреть сообщение
Нарисуйте ситуацию на листе бумаги и посмотрите, что куда указывает и куда вы пытаетесь записать данные.
Интересный способ, могли бы Вы рассказать о нём?
Цитата Сообщение от Tulosba Посмотреть сообщение
std::vector в первую очередь
Да знаю я о нём, не люблю его, люблю массивы классические, мне всегда кажется, что "указатели" быстрее работают
Цитата Сообщение от Tulosba Посмотреть сообщение
На ручном выделении/освобождении памяти далеко не уедешь
Почему? если следить, то вполне, или я не прав?
0
Модератор
Эксперт С++
11348 / 9312 / 5594
Регистрация: 18.12.2011
Сообщений: 24,849
10.09.2014, 17:53 5
В конструкторе this->name = name;
Так нельзя. Под строку выделяем память и копируем:
C++
1
2
this->name=new char[strlen(name)+1];
strcpy(this->name,name);
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
10.09.2014, 18:14  [ТС] 6
Цитата Сообщение от zss Посмотреть сообщение
strlen(name)+1
почему +1? Ведь в изначальной строке уже есть завершающий ноль?
в strcpy_s тоже надо использовать strlen(name)+1? или всё-таки strlen(name)?

Цитата Сообщение от FiLF Посмотреть сообщение
убрать &
почему тут
C++
1
_read(this->fh, &(this->num), sizeof(int));
так? int this->num
а тут
C++
1
_read(this->fh, (this->nV[i]), 3*sizeof(float));
так? int **this->nV
там где указатель на массив - & амперсант не нужен?
а там где элемент - нужен & амперсант?
0
:)
Эксперт С++
4769 / 3263 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
10.09.2014, 18:18 7
Цитата Сообщение от KokosSPb Посмотреть сообщение
почему +1? Ведь в изначальной строке уже есть завершающий ноль?
Нуль есть, но strlen() возвращает длину без него. и strcpy_s() аналогично.
Цитата Сообщение от KokosSPb Посмотреть сообщение
не люблю его, люблю массивы классические, мне всегда кажется, что "указатели" быстрее работают
Когда кажется - креститься проверять надо. В релизной версии std::vector оверхеда быть не должно по сравнению с классическими массивами.
Цитата Сообщение от KokosSPb Посмотреть сообщение
Почему? если следить, то вполне, или я не прав?
За всем не уследить. Чем сложнее проект, тем более высокоуровневые концепции приходится использовать, иначе задача просто не уместится в голове программиста.
1
15263 / 8230 / 1993
Регистрация: 30.01.2014
Сообщений: 14,014
10.09.2014, 18:19 8
Цитата Сообщение от KokosSPb Посмотреть сообщение
Почему? если следить, то вполне, или я не прав?
Бывают проекты, где количество строк кода измеряется сотнями тысяч. А логика работы, зачастую, совсем не понятна без специальных знаний. И там чтобы так "следить" нужно быть кем-то вроде бога. Для упрощения разработки и понимания вводят уровни абстракции. Так вот, например, выделение-освобождение памяти - это один уровень абстракции, работа с этой памятью - это другой. Нет ничего плохого в том, что стандартная библиотека позаботилась о вынесении менеджмента памяти в std::vector, теперь мы можем сосредоточится на работе с данными. И так во всем, это абсолютно всего касается, не только памяти и векторов. Вот у тебя классическая ошибка проектирования, класс triangles занимается перекладыванием байтов, вместо того, чтобы решать свою непосредственную задачу. Даже если ты не хочешь использовать std::vector, то все равно нужно хотя бы вручную отделить работу с памятью от работы с данными, иначе действительно далеко не уедешь.
1
54 / 54 / 37
Регистрация: 05.09.2013
Сообщений: 1,864
10.09.2014, 18:22 9
Указатель - это переменная, которая содержит адрес другой переменной. & - позволяет получить адрес переменной. Вы пытались записать данные не в массив, а в переменную, в которой хранится адрес начала массива. В итоге: повредили чью-то память и программа завершилась аварийно.
P.S. Детально ваш код не смотрел.
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
11.09.2014, 08:36  [ТС] 10
Переписал пока вот так. Верно? Есть замечания? правильно ли описан деструктор? А главное - что делать тут?
C++
1
_read(this->fh, &(this->num), sizeof(int));
triangles.cpp
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
#include "triangles.h"
 
triangles::triangles(char* name)
{
    //присваиваем имя файла(адрес)
    this->name=new char[strlen(name)+1];
    strcpy_s(this->name,strlen(name)+1,name);
    //создаем дескриптор файла на чтение
    _sopen_s(&(this->fh), this->name, _O_BINARY | _O_RDONLY, _SH_DENYRD,0);
    //читаем заголовок (он нам не интересен) и если он читается
    if(_read(this->fh, &this->num, 80*sizeof(char))!=-1)
    {
        //читаем количество треугольников
        _read(this->fh, &(this->num), sizeof(int));
        //создаем массив указателей на вектора нормалей по количеству треугольников
        this->nV = new float*[this->num];
        //создаем массив атрибутов
        this->attr = new unsigned short[this->num];
        //создаем массив указателей на указатели треугольников arr[i][вершины][координаты вершин]
        this->tr = new float**[this->num];
        for(unsigned int i = 0;i<this->num;i++)
        {
            //создаем массив вершин конца вектора нормали
            this->nV[i] = new float[3];
            //создаем массив указателей на вершины треугольников
            this->tr[i] = new float*[3];
            //читаем нормали
            _read(this->fh, this->nV[i], 3*sizeof(float));
            for(unsigned int j = 0;j<3;j++)
            {
                //создаем массив координат вершин треугольников
                this->tr[i][j] = new float[3];
                //читаем координаты вершин
                _read(this->fh, this->tr[i][j], sizeof(float)*3);
            }
            //читаем атрибуты треугольника
            _read(this->fh, &(this->attr[i]), sizeof(unsigned short));
        }
    }
    _close(fh);
};
triangles::~triangles()
{
    delete[] this->attr;
    for(unsigned int i = 0;i<this->num;i++)
        {
            delete[] this->nV[i];
            delete[] this->tr[i][0];
            delete[] this->tr[i][1];
            delete[] this->tr[i][2];
            delete[] this->tr[i];
        }
};
unsigned long triangles::get_num()
{
    return this->num;
};
float triangles::get_coord(int i,int j,int k)
{
    return this->tr[i][j][k];
};
Добавлено через 5 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Даже если ты не хочешь использовать std::vector, то все равно нужно хотя бы вручную отделить работу с памятью от работы с данными, иначе действительно далеко не уедешь.
Совет есть?:-) я бы с удовольствием, просто что ты конкретно имеешь в виду? Отдельный класс ещё (тогда они будут зависимы)? Придумать что-то в этом классе интересное? Просто очень часто мне нужны многомерные массивы с разной длиной подизмерений
Кликните здесь для просмотра всего текста
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0

и вектор, вроде, не справится с таким =)
0
15263 / 8230 / 1993
Регистрация: 30.01.2014
Сообщений: 14,014
11.09.2014, 09:43 11
Цитата Сообщение от KokosSPb Посмотреть сообщение
Совет есть?:-) я бы с удовольствием, просто что ты конкретно имеешь в виду? Отдельный класс ещё (тогда они будут зависимы)? Придумать что-то в этом классе интересное? Просто очень часто мне нужны многомерные массивы с разной длиной подизмерений
Ну вот ты же сам сформулировал задачу, дело за малым, осознать ее до конца и реализовать. Triangle - это очевидно класс из какой-то предметной области, для какой-то задачи, например геометрической. А "массив с разной длиной подизмерений" - это утилитарный класс, который может быть использован для решения какой-то задачи. Ну так вот, если тебе нужен такой массив, нужно сначала реализовать его (как отдельную сущность), а потом на его основе строить решение како-либо прикладной задачи.
Цитата Сообщение от KokosSPb Посмотреть сообщение
тогда они будут зависимы
Да, класс, решающий задачу, будет использовать класс организующий такой массив (но не наоборот). Обратимся к реальному миру. Вот есть класс "автомобиль", а есть класс "двигатель". Зависит ли автомобиль от двигателя? - очевидно, да. Зависит ли двигатель от автомобиля? - в большинстве случаев нет. Он может быть сделан каким-то другим производителем и иметь типовые характеристики. Это нормально.

Цитата Сообщение от KokosSPb Посмотреть сообщение
часто мне нужны многомерные массивы с разной длиной подизмерений
В самом простом и примитивном варианте можно сделать вектор векторов.
C++
1
std::vector< std::vector<int> > array;
У каждого внутреннего вектора свой размер.
Повторюсь, даже если не использовать вектор, все равно целесообразно разделить работу с памятью и логику. Ты сам увидишь насколько проще станет твоя программа.

Добавлено через 15 минут
Цитата Сообщение от KokosSPb Посмотреть сообщение
read(this->fh, &this->num, 80*sizeof(char))
Если num - это int, то тут ты начнешь читать в чужую память, так как sizeof(int) явно меньше чем 80*sizeof(char).
Цитата Сообщение от KokosSPb Посмотреть сообщение
А главное - что делать тут?
Что тебя смущает?
Цитата Сообщение от KokosSPb Посмотреть сообщение
правильно ли описан деструктор?
name не освобождается.
Цитата Сообщение от KokosSPb Посмотреть сообщение
triangles(char* name)
Должен быть const char *. Ты же не собираешься менять name внутри конструктора.
Цитата Сообщение от KokosSPb Посмотреть сообщение
создаем дескриптор файла на чтение
А сделать проверку на успешность открытия?
Цитата Сообщение от KokosSPb Посмотреть сообщение
Есть замечания?
Как ты думаешь, что будет, если объект такого класса кто-то захочет скопировать?
C++
1
2
3
4
5
6
triangles foo()
{
    return triangles("test.bin");
}
//.......
triangles a = foo();
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
11.09.2014, 10:34  [ТС] 12
Цитата Сообщение от DrOffset Посмотреть сообщение
Если num - это int, то тут ты начнешь читать в чужую память, так как sizeof(int) явно меньше чем 80*sizeof(char).
Цитата Сообщение от KokosSPb Посмотреть сообщение
если подскажите как перешагнуть через него буду рад
он мне вообще не нужен =(
Цитата Сообщение от DrOffset Посмотреть сообщение
Что тебя смущает?
наличие амперсанда
Цитата Сообщение от DrOffset Посмотреть сообщение
name не освобождается.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
triangles::~triangles()
{
    delete[] this->name;
    delete[] this->attr;
    for(unsigned int i = 0;i<this->num;i++)
        {
            delete[] this->nV[i];
            delete[] this->tr[i][0];
            delete[] this->tr[i][1];
            delete[] this->tr[i][2];
            delete[] this->tr[i];
        }
};
теперь верно?
Цитата Сообщение от DrOffset Посмотреть сообщение
Как ты думаешь, что будет, если объект такого класса кто-то захочет скопировать?
наверное не совсем понимаю вопрос...

Правильно ли я мыслю?
polygon.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma once
 
class polygon
{
public:
    polygon(int);
    ~polygon();
    unsigned long get_num();
    float* get_p_nV(unsigned int);
    float* get_p_tr(unsigned int,unsigned int);
    unsigned short& get_p_attr(unsigned int);
    float get_coord(int,int,int);
private:
    unsigned long num;
    float **nV;
    float ***tr;
    unsigned short *attr;
protected:
};
polygon.cpp
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
#include "polygon.h"
 
polygon::polygon(int num)
{
    //записываем количество полигонов
    this->num = num;
    //создаем массив указателей на вектора нормалей по количеству треугольников
    this->nV = new float*[this->num];
    //создаем массив атрибутов
    this->attr = new unsigned short[this->num];
    //создаем массив указателей на указатели треугольников arr[i][вершины][координаты вершин]
    this->tr = new float**[this->num];
    for(unsigned int i = 0;i<this->num;i++)
    {
        //создаем массив вершин конца вектора нормали
        this->nV[i] = new float[3];
        //создаем массив указателей на вершины треугольников
        this->tr[i] = new float*[3];
        for(unsigned int j = 0;j<3;j++)
        {
            //создаем массив координат вершин треугольников
            this->tr[i][j] = new float[3];
        }
    }
};
polygon::~polygon()
{
    delete[] this->attr;
    for(unsigned int i = 0;i<this->num;i++)
    {
        delete[] this->nV[i];
        delete[] this->tr[i][0];
        delete[] this->tr[i][1];
        delete[] this->tr[i][2];
        delete[] this->tr[i];
    }
};
unsigned long polygon::get_num()
{
    return this->num;
};
float* polygon::get_p_nV(unsigned int i)
{
    return this->nV[i];
};
float* polygon::get_p_tr(unsigned int i,unsigned int j)
{
    return this->tr[i][j];
};
unsigned short& polygon::get_p_attr(unsigned int i)
{
    return this->attr[i];
};
Всё что отвечает за хранение данных перенес в отдельный класс, верно?
0
15263 / 8230 / 1993
Регистрация: 30.01.2014
Сообщений: 14,014
11.09.2014, 13:23 13
Цитата Сообщение от KokosSPb Посмотреть сообщение
наличие амперсанда
Мы говорим записать в область памяти с адресом &num данные размером sizeof(int). Если num - int, а файл сохранялся на той же платформе, где запускается программа, то все будет нормально. Тема правильной сериализации данных - это вообще обширная область, в двух словах не расскажешь, да и не нужно это здесь в общем-то (но если интересно - можешь начать с отсюда, хотя бы получишь представление).

Цитата Сообщение от KokosSPb Посмотреть сообщение
теперь верно?
Похоже на то. Правда всю малину может испортить исключение, которое потенциально бросает new при невозможности выделить непрерывный блок заданного размера. Если это произойдет в конструкторе polygon, то деструктор ~polygon не позовется (т.к. объект считается не до конца сконструированным, пока конструктор не отработает до конца). Вот тут-то и помогли бы умные указатели Заодно деструктор упростился бы до ноля строк.

Цитата Сообщение от KokosSPb Посмотреть сообщение
наверное не совсем понимаю вопрос...
Если не реализовать правильный конструктор копирования (или не запретить копирование вовсе), то при записи, которую я выше привел, получм двойное освобождение одной и той же памяти. Конструктор копирования по-умолчанию просто скопирует указатели в новый объект. И т.к. у нас две или больше копий объекта то delete[] в их деструкторах будет вызван несколько раз для одних и тех же адресов. Скорее всего все упадет при этом.

Цитата Сообщение от KokosSPb Посмотреть сообщение
Всё что отвечает за хранение данных перенес в отдельный класс, верно?
В первом приближении да. Возможно интерфейс придется немножко дополнить удобными функциями.
Но вообще, верно или нет тебе не я подскажу, а задача твоя. Если тебе станет удобнее ее решать и понимать код - значит верно. Нужно исходить не из абстрактной "правильности" и не из того, что дядка на форуме посоветовал, а из реального положения вещей. Идея же простая, пусть каждая сущность занимается своим делом, когда в одной сущности смешивается несколько ответственностей - это усложняет ее.

Да, на учебных примерах действительно бывает сложно оценить преимущества подхода "разделяй и властвуй", но если научиться им пользоваться, то задачи действительно решаются легче. Но тут, как и везде, нужно знать меру, если разделять слишком много и без нужды (разделение ради разделения, а не ради простоты), то можно усложнить задачу в другую сторону
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
11.09.2014, 14:03  [ТС] 14
Цитата Сообщение от DrOffset Посмотреть сообщение
Да, на учебных примерах действительно бывает сложно оценить преимущества подхода "разделяй и властвуй", но если научиться им пользоваться, то задачи действительно решаются легче. Но тут, как и везде, нужно знать меру, если разделять слишком много и без нужды (разделение ради разделения, а не ради простоты), то можно усложнить задачу в другую сторону
В этом планет Т.Бадд не плохо объясняет ;-)
Цитата Сообщение от DrOffset Посмотреть сообщение
delete[] в их деструкторах будет вызван несколько раз для одних и тех же адресов. Скорее всего все упадет при этом.
Как мне сделать копирование? переопределение оператора = ? и как дальше?


с точки зрения типов возвращаемых значений, верно?
читаю файл, в котором сначала идет 80 символов заголовка, который мне не нужен (если подскажите как перешагнуть через него буду рад)
есть возможность начать читать с 81го байта?
0
Модератор
Эксперт по электронике
8517 / 6332 / 858
Регистрация: 14.02.2011
Сообщений: 22,019
11.09.2014, 14:25 15
Цитата Сообщение от KokosSPb Посмотреть сообщение
есть возможность начать читать с 81го байта?
есть
прочитай про указатели файла и функции его сдвигающие
например fseek
http://lord-n.narod.ru/downloa... /fseek.htm

Добавлено через 6 минут
кстати насчет проектирования
лучше в конструкторе не открывать/читать файлы
конструктор ничего не возвращает, как будешь обрабатывать случай что файл не открылся?
лучше в классе предусмотреть метод инициализации, и в нем читать файл
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
11.09.2014, 14:28  [ТС] 16
Добавлено через 37 секунд
Цитата Сообщение от ValeryS Посмотреть сообщение
конструктор ничего не возвращает, как будешь обрабатывать случай что файл не открылся?
Введу поле ошибки внутри объекта
0
Модератор
Эксперт по электронике
8517 / 6332 / 858
Регистрация: 14.02.2011
Сообщений: 22,019
11.09.2014, 14:32 17
Цитата Сообщение от KokosSPb Посмотреть сообщение
Введу поле ошибки внутри объекта
можно еще и исключение бросить
но зачем жизнь то себе усложнять?
если у тебя будет отдельный метод то сможешь несколько файлов в один объект прочитать
да заголовками зря разбрасываешься
он же не зря придуман
а если это будет файл неподходящего формата, например исполняемый
а анализ заголовка гарантирует что это нужный файл
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
11.09.2014, 14:52  [ТС] 18
Цитата Сообщение от ValeryS Посмотреть сообщение
да заголовками зря разбрасываешься
он же не зря придуман
а если это будет файл неподходящего формата, например исполняемый
а анализ заголовка гарантирует что это нужный файл
а по подробнее?:-)
0
Модератор
Эксперт по электронике
8517 / 6332 / 858
Регистрация: 14.02.2011
Сообщений: 22,019
11.09.2014, 19:28 19
Цитата Сообщение от KokosSPb Посмотреть сообщение
а по подробнее?:-)
а мне трудно сказать поподробнее не зная файл какого формата ты обрабатываешь
но к примеру исполняемый файл для виндовс
сначала два байта "MZ" по имени разработчика Марка Збиковски, или PE дальше ДОС заголовок, потом Видос заголовок,которые говорят что за файл под какой системой исполняются способ загрузки, и еще куча всего
подробности тут
https://ru.wikipedia.org/wiki/.EXE
или например RIFF файлы (Wav avi mid ....)
https://ru.wikipedia.org/wiki/RIFF
расширение файла есть очень не уверенная единица, если учесть что юникс системы вообще на расширение плюют.
анализ содержимого файла как раз и приходится на заголовок
если ты работаешь с 3DS файлами то вот их формат
http://www.codenet.ru/progr/formt/3ds.php
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
12.09.2014, 08:56  [ТС] 20
Цитата Сообщение от ValeryS Посмотреть сообщение
а
Я понял о чем ты, просто не догнал сначала.
Не, я пользуюсь STL форматом, в заголовке написано в какой программе он сделан, и мне эта информация действительно не нужна, CAD систем много, чтение файла от этого не меняется
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.09.2014, 08:56

Необработанное исключение в "0x00412b4a" в "kursovik.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00000004".
Программа компилируется нормально но потом на строчке MoveToEx(hdc,Mas.a]-&gt;x*20,Mas.a]-&gt;y*20,0);...

Необработанное исключение в "0x0fc1d484 (msvcr100d.dll)" в "1.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00aee0af"
помогите разобраться в чем ошибка? необходимо, чтобы ввод массива осуществлялся с клавиатуры...

Необработанное исключение в "0x1027c9c7 (msvcr100d.dll)" в "gh.exe": 0xC0000005: Нарушение прав доступа при чтении "0xfeeefeee".
// gh.cpp: определяет точку входа для консольного приложения. // #include &quot;stdafx.h&quot; #include...

Необработанное исключение в "0x76f015de" в "контрольная 1 задача 2.exe": 0xC0000005: Нарушение прав доступа при чтении "0x334e2c64"
доброго времени суток. Необработанное исключение в &quot;0x76f015de&quot; в &quot;контрольная 1 задача 2.exe&quot;:...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.