![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| alexanderd |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 3.11.2011 Репутация: нет Всего: нет |
Здравствуйте.
Возникла трабла непонятного происхождения при работе с памятью. Есть следующий код:
dataBuffer - структура, которая описывает буфер определенного размера, куда сваливаются все данные, полученные с сокета, buff- указатель на хвост буфера В цикле получаем данные с сокета и дописываем их в конец буфера. Данные нормально приняты и записаны в буфер. После получения данные из буфера пишутся в файл. Возникла необходимость выкидывать первые четыре байта из каждой порции данных, полученной с сокета. Первое и пока единственное, что пришло на ум:
Создаем временный буфер tmp_buff и записываем данные в него, затем перемещаем(или копируем) данные из него в основной буфер со смещением в четыре байта. На передающей стороне происходит следующее: с диска считывается файл по куску в 1400 байт. К этому куску добавляется заголовок в 4 байта и вот эти вот 1404 байта я получаю у себя. Потом я отбрасываю четырехбайтовый заголовок, а блок, записываю в буфер. И продолжаю писать в буфер до тех пор, пока передающая сторона полностью не отправит мне файл. После этого соединение разрывается. А из буфера данные перекидываются в файл. В итоге исходный файл и файл, записанный мной, отличаются по размерам, не более чем на килобайт при размере самого файла в несколько метров. И разница в размерах кратна четырем. При этом, если передающая сторона не добавляет заголовок, и я убираю код, по обработке заголовков, то никаких проблем не возникает... Не знаю даже в какую сторону копать... ((( Буду признателен всем за помощь PS. В кач-ве среды разработки используется MSVS2008, компилятор родной для этой среды, никаких опции не менял |
||||
|
|||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
во-первых, использование memmove не оптимально. Так как memmove делает 2 операции копирования + одну выделения и одну освобождения памяти. Лучше используй memcpy, если исходный буфер и буфер назначения не пересекаются.
во-вторых, я бы делал через считывание первых 4-х байт во временный буфер, а затем уже остальных данных в основной буфер. Но в целов в твоем коде ошибок не видно. Ты точно уверен, что проблема не в отправляющей стороне? Точно приходит по 1404 байт? |
|||
|
||||
| volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
bsa, я не смотрел исходники memmove, но думаю что задачу копирования пересекающихся областей можно сделать без 2 операций копирования и выделения. пример (упрощенный)
alexanderd, так как код отправляющей стороны вы не привели, приходиться гадать на кофейной гуще. Очень похоже, что идет выравнивание структуры на 8 байт. В итоге получается не 1404, и 1408 байт. Нужен код отправляющей стороны. Это сообщение отредактировал(а) volatile - 4.11.2011, 00:35 |
||||
|
|||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Возможно, нужно не игнорировать заголовок, а обрабатывать его.
Например, там может быть смещение от начала файла, а некоторые куски по каким-то причинам передаются дважды memmove() работает примерно так, как описал volatile - основной цикл - это команда rep movs с установленным предварительно флагом напрвления копирования; но в данном случае можно использовать memcpy(), так как буферы не пересекаются (не будет проверки на пересечение) |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Недавно тут обсуждали реализацию memmove от MS. Так там именно описанная мной реализация и была. Естественно, что с точки зрения логики делать нужно было так. |
|||
|
||||
| volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
bsa, M$ конечно много всякой фигни поднаделало, и лишний раз кинуть камень в их огород считается хорошим тоном. Но давайте будем объективны. У них получился очень недурственный компилер С++ в плане оптимизации. Не в обиду поклонникам других систем! MS конечно-же отстает в добавлении новых фич, как то новые стандарты, и т.д. это да! Но что у них не отнять, это очень и очень неплохая оптимизация! я просто не верю что они могли прошляпить такую вещь. Добавлено через 9 минут и 39 секунд Вот заглянул в crt 2008 студии Исходник общей ( не оптимизированной ) memmove.c
Добавлено через 13 минут и 32 секунды Вот здесь memmove под ARM процессоры (асм). |
||||
|
|||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
||||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |