Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
#1

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

23.11.2011, 22:35. Просмотров 1963. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.11.2011, 22:35
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обмен данными между процессами с помощью файлов, которые отображаются в память (C++):

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

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

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

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

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

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

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

Цитата Сообщение от mc.Duck Посмотреть сообщение
поэтому в массив из 10 символов влезет только 9.
Тогда терялся бы последний байт, а выпадает первый. О чём я, опять же, сказал в первом посте.
Вы же не хотите сказать, что нуль-терминированные строки символ окончания пишут своим первым байтом?
0
BRcr
4009 / 2298 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 20:20 #6
Цитата Сообщение от 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  [ТС] #7
Цитата Сообщение от BRcr Посмотреть сообщение
первый байт все еще установлен во время передачи параметров функции CopyMemory или после завершения работы этой функции, то есть во время начала выполнения строчки
C++
1
PulseEvent(hEvent1);
?
И во время, и после.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.11.2011, 20:35 #8
Цитата Сообщение от sergeyotro Посмотреть сообщение
Вы же не хотите сказать, что нуль-терминированные строки символ окончания пишут своим первым байтом?
Ну я не знаю твоего формата, может ты и перевернул строки. Только как это отразится на том, какой байт терять?

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

Цитата Сообщение от taras atavin Посмотреть сообщение
И есть ещё формат строк, в котором первый байт - счётчик, а терминального ноля нет, но в восьми битах максимально можно закодировать не 99, а 255. Если же байтов счётчика сделать два, то для всех строк короче 256-ти символов первый байт будет обнулён.
Это явно не мой случай.
0
BRcr
4009 / 2298 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 21:08 #10
Посмотрите вот здесь. Кажется, проблемы схожи, хоть суть их и не вполне ясна.
Попробуйте писать массив в файл с индекса 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  [ТС] #11
Цитата Сообщение от BRcr Посмотреть сообщение
Посмотрите вот здесь. Кажется, проблемы схожи, хоть суть их и не вполне ясна.
Попробуйте писать массив в файл с индекса 1, что-то вроде этого:
C++
1
2
int * int_ptr = (int *)StartMFile;
CopyMemory( &int_ptr[1], Buf, 99 );
Попробовал, мимо.
В данной ситуации, без поинтера, всё выглядит вот так всё:
Это происходит у "писателя"


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

Добавлено через 10 минут
И, сдается мне, на крайний случай можно-таки писать в файл/читать из него, исключая первый байт.
Инкремент адреса файла в памяти на размер одного элемента массива - вполне осуществимая вещь.
0
sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 22:58  [ТС] #13
Цитата Сообщение от BRcr Посмотреть сообщение
Какая странная штука
Порылся в справке по WinApi функциям, что вы используете - все, по идее, должно быть в норме...
Остается, по ходу, одно: trace into в debugger'e до тех пор, пока состояние первого байта не изменится...
Судя по всему - виной всему cin.getline(). Я добавил функцию cin.clear(), после PulseEvent(hEvent1) и теперь, при вводе строки, размером больше 99 символов, "читатели" получают строку из символов, которые идут после порога превышения размера. То есть если ввести 99 символов "а" и после ввести "asdf", то читатели получат именно "asdf".
Странное поведение cin.
0
BRcr
4009 / 2298 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 23:30 #14
Когда getline выбирает из потока 99 символов, она не только прекращает выборку, но и ставит потоку флаг failbit, что, вероятно, мешает функции getline получить повторный доступ к потоку на втором проходе цикла do{}while. Возможно, в этом причина изменения первого байта файла - на втором проходе цикла функция getline обламывается и пишет в буфер первый байт нулевым, затем буфер копируется в файл и читатели получают свою null-started string.
Вызов clear() очищает все флаги ошибок и на повторном доступе к потоку функция getline выбирает то, что там осталось и добросовестно пишет в буфер, который не менее добросовестно копируется в файл.
Теоретически, как-то такО_о
0
26.11.2011, 23:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2011, 23:30
Привет! Вот еще темы с ответами:

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

Обмен данными между 2 клиентами через интернет - C++
Пожалуйста, подробно опишите, как сделать обмен данных через интернет между клиентами. На с++, или на delphi код - не особо важно. Данные...

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

Провести обмен данными между двумя массивами по условию - C++
Собственно имеется следующая задача. П.5. 18.Правил Запрещено размещать задания и решения в виде картинок и других файлов с их текстом....


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

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

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