LINUX.ORG.RU

[C++] работа с памятью

 


0

2

Добрый вечер.

Насколько я помню, стандарт C++ довольно ревниво относился к неаккуратной работой с памятью. А именно, меня интересует следующий вопрос: имеется код (одна старая игра), который работает с сетью - получает и отправляет сообщения. Все сообщения сваливаются в один буфер, одно за другим. То есть, сперва может хранится int16, потом, прямо за ним без всякого padding'a структура, итд. Следовательно, некоторые типы хранятся невыровненными в естественных для них границах. После чего может спокойно делаться:

Type * ptr = (Type *)&buffer[offset];
ptr->field = ...

Я знаю, что согласно стандарту это плохо, но вопрос в следующем - могут ли возникнуть реальные проблемы с этим кодом на хоть сколько нибудь распространённых архитектурах ?

И ещё один вопрос, как относится стандарт к прямому доступу к элементам std::vector, например:

vector<byte> data;
data.resize(64);
memcpy(&data[10], src, count);
// итп.

Насколько я знаю, покуда не использовать vector<bool> реальных проблем быть не должно, но что говорит стандарт ? Если что, я в курсе про std::copy. Просто в коде с которым приходится работать имеется множество велосипедов в виде полунедоделанных структур данных. Хотелось бы заменить лишние сущности на vector. Проблема в том, что эти велосипеды раздавали свои 'char * data_ptr' налево и направо, и огромное количество кода работает с их памятью напрямую.

★★★★

> могут ли возникнуть реальные проблемы с этим кодом на хоть сколько нибудь распространённых архитектурах ?

Могу соврать, но на x86 можно напороться. Помнится, в SSE есть «быстрые» инструкции чтения и записи, которые ошибаются, если передать им недостаточно круглый адрес. Так что лучше всё-таки заводить переменную типа Type и делать в неё memcpy. Это в сях, в плюсах более интересная церемония, но суть та же.

const86 ★★★★★
()

мне кажется такими вещами лучше не заниматься, чтобы не получить увлекательных приключений с gdb в самый неподходящий момент.

mono ★★★★★
()

Насколько я знаю, покуда не использовать vector<bool> реальных проблем быть не должно, но что говорит стандарт ?

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

Я знаю, что согласно стандарту это плохо, но вопрос в следующем - могут ли возникнуть реальные проблемы с этим кодом на хоть сколько нибудь распространённых архитектурах ?

На x86/x86_64 проблем не будет, а на какой-нибудь альфе есть вероятность получить bus error

Reset ★★★★★
()

>Я знаю, что согласно стандарту это плохо, но вопрос в следующем - могут ли возникнуть реальные проблемы с этим кодом на хоть сколько нибудь распространённых архитектурах ?

На x86/x86-64 в определенных случаях можно получить тормоза. На ARM - ошибка доступа к памяти. Или адрес чтения/записи может втихую «округляться».

dmitry_vk ★★★
()

1. Структура Type, как минимум должна быть упакована. 2. На моторолоской архитектуре 68000 может быть проблема. Если доступ к word и dword идет по не выровненому адресу то будет, что то вроде bus error. Точно не помню - последний раз 3 года назад работал с этой архитектурой. 3. Если принимающая сторона и посылающая имеют разный тип Endian, то в полях структуры будет не то, что вы ожидаете. Нужно конвертировать.

Grindz
()

Всем спасибо за ответы, буду иметь ввиду.

runtime ★★★★
() автор топика

Поэтому данные по сети надо гонять сериализованными в строки :3 В JSON какой-нибудь, например. Самый неубиваемый путь

anonymous
()
Ответ на: комментарий от Reset

>> vector<bool>

Стандарт гарантирует совместимость вектора с обычным Сишным массивом.

У нас вроде вектор bool-ов особенный и он как раз ничего не гарантирует. Или я что-то путаю?

pathfinder ★★★★
()
Ответ на: комментарий от Reset

>vector < bool > это, естественно, особый случай

Пардон. Не внимательно читал.

pathfinder ★★★★
()
Ответ на: комментарий от anonymous

>Поэтому данные по сети надо гонять сериализованными в строки :3 В JSON какой-нибудь, например. Самый неубиваемый путь

Общающимся сторонам достаточно договориться о endian или даже проще, всегда использовать только сетевой порядок байт во время передачи по сети.

staseg ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.