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

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

23.11.2011, 22:35. Показов 5335. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Классическая задача "читатели-писатели", обмен информацией должен проходить с помощью файлов, отображаемых в память. Задание уже готово, но имеет один неприятный баг - при дебагинге видно, что при вводе длинных строк программа вешается, из-за того, что первый байт файла в памяти, почему-то, устанавливается в нуль. Собственно, прошу объяснений и помощи, форумчане.

Ниже фрагменты программы, в которых идёт конкретно работа с файлом. Эта ошибка происходит где-то тут.

Код писателя:
C++
1
2
3
4
5
6
7
8
hMFile = CreateFileMapping ( (HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 99, Fn1);
StartMFile = MapViewOfFile ( hMFile, FILE_MAP_WRITE, 0, 0, 99);
char * Buf = new char[99];
do {
    cin.getline(Buf, 99);
    CopyMemory(StartMFile, Buf, 99); //Вот тут в StartMFile первый байт всё ещё установлен
    PulseEvent(hEvent1);
} while ( CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, Buf, -1, "=exit", -1) != CSTR_EQUAL );
Код читателя:
C++
1
2
3
4
5
6
7
8
hMFile = OpenFileMapping(FILE_MAP_READ, TRUE, Fn1);
StartMFile = MapViewOfFile(hMFile, FILE_MAP_READ, 0, 0, 99);
char * Buf = new char[99];
do {
    WaitForSingleObject(hEvent1, INFINITE);
    CopyMemory(Buf, StartMFile, 99); // А уже тут первый байт StartMFilе равен нулю
    cout << Name << ": we have this stuff: " << Buf << endl;
} while( CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, Buf, -1, "=exit", -1) != CSTR_EQUAL );
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.11.2011, 22:35
Ответы с готовыми решениями:

Обмен данными между процессами
Добрый день! Нужно распараллелить программу. Суть в следующем: должны быть два процесса(разные функции), идущих параллельно, и второй...

Обмен данными между процессами
Уважаемое сообщество, подскажите, пожалуйста, с решением такой проблемы: у меня два процесса c# и с++, и мне необходимо передавать массив...

Обмен данными между двумя процессами
Добрый день/вечер. Усердно слушал преподавателя на паре, прошуршал много литературы дома, но так и не понял, как заюзать обмен данными...

13
Заблокирован
26.11.2011, 17:27
sergeyotro, есть вероятность, что строка более 99 символов. У тебя же в массиве их только 99...
0
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 18:00  [ТС]
Цитата Сообщение от mc.Duck Посмотреть сообщение
sergeyotro, есть вероятность, что строка более 99 символов. У тебя же в массиве их только 99...
Я в курсе, да. Поэтому и написал, что проблема проявляется только с длинными строками.
Если строка больше 99 символов - то в файл, отображаемый в память, пишется только 99 и не больше.
Вопрос не в переполнении, а в том, куда пропадает 1 байт, когда клиент копирует данные себе.
0
Заблокирован
26.11.2011, 18:24
sergeyotro, дело в том, что у строк есть завершающий нуль-символ, поэтому в массив из 10 символов влезет только 9.
0
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 19:54  [ТС]
Цитата Сообщение от mc.Duck Посмотреть сообщение
sergeyotro, дело в том, что у строк есть завершающий нуль-символ,
[сарказм]Ох, да неужели![/сарказм]

Цитата Сообщение от mc.Duck Посмотреть сообщение
поэтому в массив из 10 символов влезет только 9.
Тогда терялся бы последний байт, а выпадает первый. О чём я, опять же, сказал в первом посте.
Вы же не хотите сказать, что нуль-терминированные строки символ окончания пишут своим первым байтом?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
26.11.2011, 20:20
Цитата Сообщение от sergeyotro Посмотреть сообщение
C++
1
CopyMemory(StartMFile, Buf, 99); //Вот тут в StartMFile первый байт всё ещё установлен
первый байт все еще установлен во время передачи параметров функции CopyMemory или после завершения работы этой функции, то есть во время начала выполнения строчки
C++
1
PulseEvent(hEvent1);
?
0
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 20:30  [ТС]
Цитата Сообщение от BRcr Посмотреть сообщение
первый байт все еще установлен во время передачи параметров функции CopyMemory или после завершения работы этой функции, то есть во время начала выполнения строчки
C++
1
PulseEvent(hEvent1);
?
И во время, и после.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2011, 20:35
Цитата Сообщение от sergeyotro Посмотреть сообщение
Вы же не хотите сказать, что нуль-терминированные строки символ окончания пишут своим первым байтом?
Ну я не знаю твоего формата, может ты и перевернул строки. Только как это отразится на том, какой байт терять?

Добавлено через 1 минуту
И есть ещё формат строк, в котором первый байт - счётчик, а терминального ноля нет, но в восьми битах максимально можно закодировать не 99, а 255. Если же байтов счётчика сделать два, то для всех строк короче 256-ти символов первый байт будет обнулён.
0
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 20:57  [ТС]
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну я не знаю твоего формата, может ты и перевернул строки. Только как это отразится на том, какой байт терять?
Приведенные фрагменты кода - это вся обработка строк. Нету тут подобного формата.

Цитата Сообщение от taras atavin Посмотреть сообщение
И есть ещё формат строк, в котором первый байт - счётчик, а терминального ноля нет, но в восьми битах максимально можно закодировать не 99, а 255. Если же байтов счётчика сделать два, то для всех строк короче 256-ти символов первый байт будет обнулён.
Это явно не мой случай.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
26.11.2011, 21:08
Посмотрите вот здесь. Кажется, проблемы схожи, хоть суть их и не вполне ясна.
Попробуйте писать массив в файл с индекса 1, что-то вроде этого:
C++
1
2
int * int_ptr = (int *)StartMFile;
CopyMemory( &int_ptr[1], Buf, 99 );
0
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 21:46  [ТС]
Цитата Сообщение от BRcr Посмотреть сообщение
Посмотрите вот здесь. Кажется, проблемы схожи, хоть суть их и не вполне ясна.
Попробуйте писать массив в файл с индекса 1, что-то вроде этого:
C++
1
2
int * int_ptr = (int *)StartMFile;
CopyMemory( &int_ptr[1], Buf, 99 );
Попробовал, мимо.
В данной ситуации, без поинтера, всё выглядит вот так всё:
Это происходит у "писателя"


А это происходит у читателя, первый бит в нуль.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
26.11.2011, 22:53
Какая странная штука
Порылся в справке по WinApi функциям, что вы используете - все, по идее, должно быть в норме...
Остается, по ходу, одно: trace into в debugger'e до тех пор, пока состояние первого байта не изменится...

Добавлено через 10 минут
И, сдается мне, на крайний случай можно-таки писать в файл/читать из него, исключая первый байт.
Инкремент адреса файла в памяти на размер одного элемента массива - вполне осуществимая вещь.
0
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 22:58  [ТС]
Цитата Сообщение от BRcr Посмотреть сообщение
Какая странная штука
Порылся в справке по WinApi функциям, что вы используете - все, по идее, должно быть в норме...
Остается, по ходу, одно: trace into в debugger'e до тех пор, пока состояние первого байта не изменится...
Судя по всему - виной всему cin.getline(). Я добавил функцию cin.clear(), после PulseEvent(hEvent1) и теперь, при вводе строки, размером больше 99 символов, "читатели" получают строку из символов, которые идут после порога превышения размера. То есть если ввести 99 символов "а" и после ввести "asdf", то читатели получат именно "asdf".
Странное поведение cin.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
26.11.2011, 23:30
Когда getline выбирает из потока 99 символов, она не только прекращает выборку, но и ставит потоку флаг failbit, что, вероятно, мешает функции getline получить повторный доступ к потоку на втором проходе цикла do{}while. Возможно, в этом причина изменения первого байта файла - на втором проходе цикла функция getline обламывается и пишет в буфер первый байт нулевым, затем буфер копируется в файл и читатели получают свою null-started string.
Вызов clear() очищает все флаги ошибок и на повторном доступе к потоку функция getline выбирает то, что там осталось и добросовестно пишет в буфер, который не менее добросовестно копируется в файл.
Теоретически, как-то такО_о
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.11.2011, 23:30
Помогаю со студенческими работами здесь

Обмен данными между процессами в консольных приложениях
Привет. Можно ли как - то обмениваться данными между двумя запущенными консольными приложениями без WinAPI и без использования файлов...

Обмен данными между процессами
При создании дочернего процесса при помощи функции BOOL CreateProcess ( LPCTSTR lpApplicationName, // имя...

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

Технология обмен данными между приложениями
Приветствую профессионалов и любителей программирования! Принимайте новичка. Собственно такой вопрос, скорее системного характера....

Обмен данными между двумя динамическими массивами
Необходимо написать программу обмена данными между двумя динамическими массивами


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru