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

Ошибка доступа на break - C++

Восстановить пароль Регистрация
 
ulafrl
0 / 0 / 0
Регистрация: 25.07.2014
Сообщений: 4
25.07.2014, 16:41     Ошибка доступа на break #1
Здравствуйте!
Пишу программу, по сути являющуюся мини базой данных, в которой должна быть возможность сохранить и загрузить базу.
Сохранение вроде как работает, но вот с загрузкой проблемы.
Если смотреть по отладчику, то считывание происходит корректно, но на строчке 199 (break) происходит ошибка "нарушение прав доступа при чтении..."
Код:
Кликните здесь для просмотра всего текста
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <string>
#include <iostream>
#include <conio.h>
#include <ctype.h>
#include <vector>
#include <fstream>
using namespace std;
 
struct mystructure
{
    string model;
    string mark;
    int frequency;
    int RAM;
    string markHDD;
    int storHDD;
    bool GPU;
    double price;
};
 
 
class computer
{
private:
    string model;
    string mark;
    int frequency;
    int RAM;
    string markHDD;
    int storHDD;
    bool GPU;
    double price;
public:
    computer() {};
    ~computer() {};
    friend void vvod(computer &ob);
    friend void vyvod(computer &ob);
    friend void shortstream(computer& ob);
    friend mystructure savebase(computer& ob);
    friend computer openbase(mystructure& ob);
};
 
void shortstream(computer& ob)
{
    cout << ob.mark << "  -  " << ob.model;
};
 
void vvod(computer &ob)
{
    system("cls");
    cout << "Введите название производителя ПК:\n";
    cin >> ob.mark;
    cout << "Введите модель ПК:\n";
    cin >> ob.model;
    cout << "Введите тактовую частоту CPU (MHz):\n";
    cin >> ob.frequency;
    cout << "Введите объём оперативной памяти (MB):\n";
    cin >> ob.RAM;
    cout << "Введите название производителя HDD:\n";
    cin >> ob.markHDD;
    cout << "Введите объём HDD (GB):\n";
    cin >> ob.storHDD;
    cout << "Имеется ли дискретный GPU? (0 - нет, 1 - да)\n";
    cin >> ob.GPU;
    cout << "Введите цену ПК ($):\n";
    cin >> ob.price;
};
 
void vyvod(computer &ob)
{
    cout << "Производитель: " << ob.mark << endl;
    cout << "Модель: " << ob.model << endl;
    cout << "Частота CPU: " << ob.frequency << " MHz" << endl;
    cout << "RAM: " << ob.RAM << " MB" << endl;
    cout << "Производитель HDD: " << ob.markHDD << endl;
    cout << "Объём HDD: " << ob.storHDD << " GB" << endl;
    if (ob.GPU = false)
        cout << "Дискретный GPU: Нет" << endl;
    else
        cout << "Дискретный GPU: Да" << endl;
    cout << "Цена: " << ob.price << "$" << endl;
};
 
mystructure savebase(computer& ob)
{
    mystructure temp;
    temp.model = ob.model;
    temp.mark = ob.mark;
    temp.frequency = ob.frequency;
    temp.RAM = ob.RAM;
    temp.markHDD = ob.markHDD;
    temp.storHDD = ob.storHDD;
    temp.GPU = ob.GPU;
    temp.price = ob.price;
    return temp;
};
 
computer openbase(mystructure& ob)
{
    computer temp;
    temp.model = ob.model;
    temp.mark = ob.mark;
    temp.frequency = ob.frequency;
    temp.RAM = ob.RAM;
    temp.markHDD = ob.markHDD;
    temp.storHDD = ob.storHDD;
    temp.GPU = ob.GPU;
    temp.price = ob.price;
    return temp;
};
 
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
 
    vector<computer>base;
 
    int key = 0;
    while (key != 27)
    {
        system("cls");
        cout << "Для выбора пункта меню нажмите соответствующую клавишу\n" << endl;
        cout << "1  - Добавить ПК в базу\n"
            << "2   - Краткий список ПК в базе\n"
            << "    - Удалить ПК из базы\n"
            << "    - Поиск (не работает нихрена)\n"
            << "9   - Сохранить базу\n"
            << "0   - Загрузить базу\n"
            << "ESC - Выход" << endl;
        key = _getch();
 
        switch (key)
        {
        case 49: //1    - Добавить ПК в базу
        {
            computer temp = computer();
            vvod(temp);
            base.push_back(temp);
            temp.~computer();
            break;
        }
        case 50: // 2 - Краткий список ПК в базе
        {
            int kol = base.size();
            if (kol != 0)
            {
                for (int i = 0; i < kol; i++)
                {
                    cout << i + 1 << ") ";
                    shortstream(base[i]);
                    cout << endl;
 
                }
            }
            system("pause");
            break;
        }
        case 57: //9    - Сохранить базу
        {
            system("cls");
            string filename;
            cout << "Введите имя файла: "; cin >> filename;
            mystructure temp;
            int length = 0; int kol = base.size();
            ofstream file(filename + ".db"); filename.clear;
            file.clear();
            //file.seekp(0, ios::end);
            file.write((char*)&kol, sizeof(int));
            for (int i = 0; i < base.size(); i++)
            {
                temp = savebase(base[i]);
                length = sizeof(temp);
                file.write((char*)&length, sizeof(int));
                file.write((char*)&temp, length);
            }
            file.close();
            break;
        }
        case 48: //0    - Загрузить базу
        {
            system("cls");
            base.clear();
            string filename;
            cout << "Введите имя файла: "; cin >> filename;
            mystructure temp;
            int length = 0; int kol = 0;
            ifstream file(filename + ".db"); filename.clear;
            //file.seekg(0, ios::beg);
            file.read((char*)&kol, sizeof(int));
            for (int i = 0; i < kol; i++)
            {
                file.read((char*)&length, sizeof(int));
                file.read((char*)&temp, length);
                base.push_back(openbase(temp));
            }
            file.close();
            break;
        }
        }
    }
    base.~vector();
    return 0;
};


Почему, собственно, так происходит, если всё успешно считывается?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.07.2014, 16:41     Ошибка доступа на break
Посмотрите здесь:

C++ Ошибка: Нарушение прав доступа
Ошибка доступа к полю C++
C++ Ошибка доступа при записи
C++ RTTI ошибка прав доступа
Ошибка доступа после fclose C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
25.07.2014, 16:52     Ошибка доступа на break #2
C++
1
ifstream file(filename + ".db");
Файл открывается в текстовом режиме.

C++
1
2
3
mystructure temp;
....
file.read((char*)&temp, length);
Читать пытаемся в бинарном режиме.
C++
1
2
3
4
5
6
7
8
9
10
11
struct mystructure
{
    string model;
    string mark;
    int frequency;
    int RAM;
    string markHDD;
    int storHDD;
    bool GPU;
    double price;
};
Структуры, сожержащие std::string так писать/читать нельзя.

C++
1
base.~vector();
Явно звать деструктор не надо.
Ну как-то так для начала.
ulafrl
0 / 0 / 0
Регистрация: 25.07.2014
Сообщений: 4
25.07.2014, 17:12  [ТС]     Ошибка доступа на break #3
А как писать стуктуры со string?

Кстати, если на этом break (199 строка) поставить точку останова, то при, собственно, остановке в локальных переменных можно увидеть что всё считано верно. В структуре temp и векторе base все данные на своих местах.
Если запись/чтение у меня реализовано не верно, то по идее он и читать ничего не должен был бы, ведь так?
zer0mail
2189 / 1872 / 187
Регистрация: 03.07.2012
Сообщений: 6,665
Записей в блоге: 1
25.07.2014, 17:31     Ошибка доступа на break #4
ТС, раз проблема с чтением файла, то прикрепляй сам читаемый файл к теме.
ulafrl
0 / 0 / 0
Регистрация: 25.07.2014
Сообщений: 4
25.07.2014, 17:37  [ТС]     Ошибка доступа на break #5
[cut]Файл
Создан этой же программой.
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
25.07.2014, 17:51     Ошибка доступа на break #6
Цитата Сообщение от ulafrl Посмотреть сообщение
А как писать стуктуры со string?
Засада в том, что строка хранит только указатель на данные на куче:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct ppl_age
{
  std::string name;
  int age;
};
 
int main()
{
  ppl_age test;
  std::cout<<"size of empty struct="<<sizeof(test)<<"\n";
  test.name = "this is test string for name";
  std::cout<<"size of filled struct="<<sizeof(test)<<"\n";
  return 0;
}
Причем читал когда-то что есть реализация stl, в которой string хранит данные внутри до определенного объема.

По этому такую структуру читать-писать проще в текстовом режиме:
Кликните здесь для просмотра всего текста

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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <clocale>
#include <algorithm>
#include <sstream>
 
using namespace std;
 
 
struct ppl_age
{
  std::string name;
  int age;
};
 
std::ostream& operator<< (std::ostream& stream, const ppl_age& age_rec)
{
   stream<<age_rec.name;
   stream<<" ";
   stream<<age_rec.age;
   return stream;
}
 
std::istream& operator>> (std::istream& stream, ppl_age& age_rec)
{
   stream>>age_rec.name;
   stream>>age_rec.age;
   return stream;
}
 
bool createTestFile()
{
   std::vector<ppl_age> age_records;
   ppl_age new_age_rec;
   new_age_rec.name = "btest";
   new_age_rec.age = 10;
   age_records.push_back(new_age_rec);
   new_age_rec.name = "btest";
   new_age_rec.age = 20;
   age_records.push_back(new_age_rec);
   new_age_rec.name = "atest";
   new_age_rec.age = 20;
   age_records.push_back(new_age_rec);
   ofstream fout;
   fout.open("ppl.txt");
   if(fout.is_open())
   {
      for(unsigned age_cnt = 0; age_cnt<age_records.size();age_cnt++)
      {
         fout << age_records[age_cnt] << endl;
      }
      fout.close();
   }
   else
   {
      cout << "Can't open output file" << endl;
      return false;
   }
   return true;
}
 
int main()
{
   createTestFile();
   std::vector<ppl_age> age_records;
   ifstream fin;
   fin.open ("ppl.txt");
   if(fin.is_open())
   {
      while(true)
      {
         ppl_age new_age_rec;
         fin>>new_age_rec;
         if(fin.good())
            age_records.push_back(new_age_rec);
         else
            break;
      }
      fin.close();
   }
   for(unsigned age_cnt = 0; age_cnt<age_records.size();age_cnt++)
   {
      cout << age_records[age_cnt] << endl;
   }
   system ("pause");
   return 0;
}


Добавлено через 3 минуты
Второй вариант - заменить string на символьный массив фиксированного размера.
Yandex
Объявления
25.07.2014, 17:51     Ошибка доступа на break
Ответ Создать тему
Опции темы

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