Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 01.11.2012
Сообщений: 8

Чтение из бинарного файла - неведомое исключение

01.11.2012, 16:14. Показов 2798. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.
Помоги понять почему вылетает с ошибкой:
Необработанное исключение в "0x5a93ad54 (msvcp100d.dll)" в "test_conlose.exe": 0xC0000005: Нарушение прав доступа при записи "0xfeeefeee".

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
#include <iostream>
#include <string>
#include <fstream>
 
using namespace std;
 
int main()
{
    string s1("111111"), s2("2222");
 
    ofstream save( "data.bin", ios::binary | ios::out );
 
    if( save ) 
    {
        save.write( reinterpret_cast <char *> ( &s1 ), sizeof( string ) ); 
        save.close();
    }
    else system("pause");
 
    ifstream load( "data.bin", ios::binary );
 
    if( load )
    {
        load.read( reinterpret_cast <char *> ( &s2 ), sizeof( string ) );
        load.close();
    }
 
    cout << s2 << "\n";
 
    system("pause");
    return 0;
}
Если стринг заменить на инт, то не вылетает. Объясните пожалуйста почему.
Просьба предлагать только решения на c++, через потоки.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.11.2012, 16:14
Ответы с готовыми решениями:

Чтение/запись бинарного файла: необработаное исключение
Здравствуйте. Есть данный код: #ifdef _MSC_VER #define _CRT_SECURE_NO_WARNINGS #endif #include &lt;iostream&gt; #include...

Чтение бинарного файла - чтение первых 9 байт
Есть код, который читает первые 9 байт бинарного файла(заголовок записи) void ATS44Encoder::FileEncode() { QFile* file = new...

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

38
0 / 0 / 0
Регистрация: 01.11.2012
Сообщений: 8
02.11.2012, 20:18  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от alsav22 Посмотреть сообщение
Советую, в этом случае, пробовать код со своей структурой. Пример вы очень неудачно выбрали: строки, инициализированные литералами, и бинарное чтение/запись, используя адреса этих строк. Тут ошибки по разным причинам могут происходить.
я пытаюсь записать и считать класс, в котором есть значения string

Цитата Сообщение от soon Посмотреть сообщение
Тут ошибка происходит по одной причине - после считывания/копирования строки, charT* в std::string указывает на одну область памяти.
вроде доходит, спасибо пойду разбираться.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 20:24
Цитата Сообщение от soon Посмотреть сообщение
Тут
Тут, имеется ввиду, где? В каком коде? Из первого поста?
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 20:26
Цитата Сообщение от alsav22 Посмотреть сообщение
Тут, имеется ввиду, где? В каком коде? Из первого поста?
В постах ##1, 5, 6.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 20:32
Цитата Сообщение от guest658655 Посмотреть сообщение
я пытаюсь записать и считать класс, в котором есть значения string
Зачем строки таким именно способом читать/записывать? Обычно, если читается/записывается класс, то не делают чтение/запись всей памяти под объектом (потому что неизвестно,что читается/записывается в результате), а делается в классе перегрузка операторов чтения/записи и в них уже прописывается, как именно читать/записывать поля класса.

Цитата Сообщение от soon Посмотреть сообщение
В постах ##1, 5, 6.
Тут ошибка происходит по одной причине - после считывания/копирования строки, charT* в std::string указывает на одну область памяти.
И что дальше, если взять код из первого поста?
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 20:36
Цитата Сообщение от alsav22 Посмотреть сообщение
а делается в классе перегрузка операторов чтения/записи и в них уже прописывается, как именно читать/записывать поля класса.
Как же тогда в Си без перегрузок обходятся...

Добавлено через 1 минуту
Цитата Сообщение от alsav22 Посмотреть сообщение
И что дальше, если взять код из первого поста?
Каг-бе именно это весь тред мусолят, не?
0
0 / 0 / 0
Регистрация: 01.11.2012
Сообщений: 8
02.11.2012, 20:45  [ТС]
Цитата Сообщение от alsav22 Посмотреть сообщение
Зачем строки таким именно способом читать/записывать? Обычно, если читается/записывается класс, то не делают чтение/запись всей памяти под объектом (потому что неизвестно,что читается/записывается в результате), а делается в классе перегрузка операторов чтения/записи и в них уже прописывается, как именно читать/записывать поля класса.
мне надо записать примерно такой класс:

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
#include <iostream>
#include <string>
#include <fstream>
 
using namespace std;
 
class myclass
{
public:
    std::string str;
    int i;
    bool yes;
 
    myclass() { str = "empty"; i = 0; yes = true; }
};
 
int main()
{
    myclass A, B;
 
    A.str = "abc";
    A.i = 5;
    A.yes = false;
 
    std::ofstream save( "data.bin", std::ios::out | std::ios::binary );
 
    if( save ) 
    {
        save.write( reinterpret_cast <char *> ( &A ), sizeof( myclass ) );
        save.close();
    }
 
    std::ifstream load( "data.bin", std::ios::binary );
 
    if( load )
    {
        load.read( reinterpret_cast <char *> ( &B ), sizeof( myclass ) );
        load.close();
    }
 
    cout << B.str << "\n" << B.i << "\n" << B.yes << "\n";
 
    system("pause");
    return 0;
}
хотя бы кратко скажите что делать? до system("pause") доходит без проблем, но уже по завершении вылетает исключение :/
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 21:04
Ничего конкретного по коду из первому поста я не услышал. И где там что указывает на одну область памяти?

Добавлено через 16 минут
Мне кажется, в первом посте ошибка происходит из-за того, что чтение (всего объекта из файла) происходит в память, занятую объектом string, т.е. не в строку на которую указывает этот объект, а в сам объект, что вызывает ошибку нерушения прав при записи.
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 21:07
guest658655, Можете выделять память под массив char, затем его копировать в переменную std::string. Можете считывать побайтово и использовать push_pack. Вариантов масса.

alsav22, т.е. вас не смущет, что сначала объект s1 побайтово пишется в data.bin, а потом эти-же данные пишутся в объект s2?

Добавлено через 3 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Мне кажется, в первом посте ошибка происходит из-за того, что чтение происходит в память, занятую объектом string, т.е. не в строку на которую указывает этот объект,
Он никуда не указывает
Цитата Сообщение от alsav22 Посмотреть сообщение
а в сам объект, что вызывает ошибку нерушения прав при записи.
Неа. Под объект std::string выделено sizeof(std::string) байт памяти. Вы можете делать с ними все что вам захочется. В первом посте наглядно показано, к чему это может привести.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 21:11
Цитата Сообщение от soon Посмотреть сообщение
Он никуда не указывает
Разве в объекте string не содержится указатель на строку, с которой он связан?
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 21:17
alsav22, в объекте - содержится, да. Но сам объект никуда не указывает.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 21:23
Кстати, в релизе эта ошибка исчезает. И вы не ответили на вопрос:
Цитата Сообщение от alsav22 Посмотреть сообщение
И где там что указывает на одну область памяти?
И как это приводит к ошибке?

Добавлено через 48 секунд
Цитата Сообщение от soon Посмотреть сообщение
alsav22, в объекте - содержится, да. Но сам объект никуда не указывает.
Думаете я что-то другое имел ввиду?

Добавлено через 5 минут
Цитата Сообщение от soon Посмотреть сообщение
Неа. Под объект std::string выделено sizeof(std::string) байт памяти. Вы можете делать с ними все что вам захочется.
Если всё, что захочется, то почему это код вызывет такую же ошибку?
C++
1
2
string s1("111111");
scanf("%s", &s1);
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 21:28
Цитата Сообщение от alsav22 Посмотреть сообщение
Думаете я что-то другое имел ввиду?
Нет, я просто поправил.

Цитата Сообщение от alsav22 Посмотреть сообщение
Кстати, в релизе эта ошибка исчезает. И вы не ответили на вопрос:
Не ошибка исчезает, а программа не падает

Цитата Сообщение от alsav22 Посмотреть сообщение
И как это приводит к ошибке?
Я это показал в посте #6. Два объекта становятся идентичны друг другу. Следовательно, происходит повторное освобождение памяти. Упрощенно это выглядит так.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    char* str1, * str2;
 
    str1 = new char[42];
    str2 = new char[42];
 
    str2 = str1;
 
    delete[] str2;
    delete[] str1;
 
    return 0;
}
Добавлено через 4 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Если всё, что захочется, то почему это код вызывет такую же ошибку?
Там будет segfault вместо glibc detected.
C++
1
2
3
4
5
6
7
8
9
10
11
#include <cstdlib>
#include <string>
#include <iostream>
 
int main()
{
    std::string str;
    std::scanf("%s", &str);
    std::cout << "No error" << std::endl;
    return 0;
}
Ошибка будет не после записи в строку. А так вообще не будет
C++
1
2
3
4
5
6
7
8
9
10
11
#include <cstdlib>
#include <string>
#include <iostream>
 
int main()
{
    std::string* str_ptr = new std::string;
    std::scanf("%s", str_ptr);
    std::cout << "No error" << std::endl;
    return 0;
}
Смекаете, к чему я?
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 21:33
Цитата Сообщение от soon Посмотреть сообщение
Ошибка будет не после записи в строку
Это не понял. Не после записи, а когда?
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 21:36
Цитата Сообщение от alsav22 Посмотреть сообщение
Не после записи, а когда?
Когда будет освобождаться память.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
02.11.2012, 21:37
Цитата Сообщение от soon Посмотреть сообщение
А так вообще не будет
А так?
C++
1
2
3
4
string* str_ptr = new string;
scanf("%s", str_ptr);
cout << "No error" << endl;
delete str_ptr;
Добавлено через 1 минуту
Цитата Сообщение от soon Посмотреть сообщение
Когда будет освобождаться память.
И из-за чего? Где там двойной указатель на одну память?
0
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
02.11.2012, 21:50
Цитата Сообщение от alsav22 Посмотреть сообщение
А так?
Так будет.

Цитата Сообщение от alsav22 Посмотреть сообщение
И из-за чего? Где там двойной указатель на одну память?
Я уже сказал, там совсем другая ошибка. Будет вызван деструтор для std::string, а он попытается освободить занятую память. Поскольку то что мы введем будет указывать черте-куда, нам выбьет segfault. Ради интереса можете дизассемблировать и закомментить вызов деструктора(_ZNSsD1Ev в g++). Или в исходниках std::string.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.11.2012, 01:35
Останусь при своём мнении. Все эти ошибки возникают из-за того, что в память под объектом string, функциями (типа scanf(), которая понятия не имеет, как устроен объект string) или операторами, которые не определены или не перегружены в классе, дедается запись. В результате объект испорчен, поэтому в дальнейшем возникают те или иные ошибки. guest658655 совет. Для записи в объект, и для чтения тоже (записывать в файл дамп памяти под объектом не есть хорошо), всегда используйте методы класса или операторы перегруженные в классе. Эти методы и операторы, в частности для string, работают не с памятью под объектом, а с указателем на строку, который хранится в этом объекте.
1
 Аватар для soon
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
03.11.2012, 08:25
Останусь при своём мнении. Все эти ошибки возникают из-за того, что в память под объектом string, функциями (типа scanf(), которая понятия не имеет, как устроен объект string) или операторами, которые не определены или не перегружены в классе, дедается запись. В результате объект испорчен, поэтому в дальнейшем возникают те или иные ошибки.
Ваше мнение магическим образом совпадает с тем, что я пытался объяснить на протяжении 4-х страниц.
1
0 / 0 / 0
Регистрация: 01.11.2012
Сообщений: 8
03.11.2012, 10:26  [ТС]
Всем спасибо за советы, буду пробовать
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.11.2012, 10:26
Помогаю со студенческими работами здесь

Чтение нескольких структур и одной переменной из бинарного файла. Формат файла имеется
Формат файла состоит из 3 структур и одной переменной. Подробное описание формата во вложении, просьба посмотреть его. У меня возникла...

Чтение из бинарного файла
Создала Базу данных. запись в файл происходит, а чтение из файла не получается. исправьте, пожалуйста, или подскажите как? #include...

Чтение бинарного файла
Подскажите пожалуйста как можно правильно открыть бинарный файл не зная структуры? С чего мне начать? Вот пример:

Чтение бинарного файла
Всем привет!Уже вторую ночь пытаюсь разобраться с проблемой,но пока безуспешно.Проблема такая: Микроконтроллер выдает пакеты одной...

Чтение бинарного файла
Здравствуйте. Есть код чтения бинарного файла: FILE *f; string tmp; char buff = {0}; f = fopen(&quot;data.bin&quot;,...


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru