Есть ли стандарт для хранения объектов C++ в памяти? Я хочу установить указатель char * на определенный адрес в памяти, чтобы я мог читать переменные некоторых объектов непосредственно из байта памяти байтом. Когда я использую Dev C++, переменные хранятся один за другим прямо в адресе памяти объекта в том порядке, в котором они были определены. Теперь, может ли быть другим при использовании другого компилятора (например, переменные находятся в другом порядке или где-то еще)? Заранее спасибо. :-)Объект C++ в памяти
ответ
Переменные не могут быть в другом порядке, насколько я знаю. Однако между членами может быть различное количество дополнений. Также я думаю, что все ставки отключены с помощью виртуальных классов, а различные реализации пользовательских типов (например, std :: string) могут быть совершенно разными между библиотеками (или даже вариантами сборки).
Кажется, очень подозрительная вещь. Что вам нужно для: доступа к частным членам?
Переменные могут быть в другом порядке, если у них есть спецификаторы доступа между ними. Например, 'public: int x; int y; 'должно быть в порядке. 'public: int x; public: int y; 'не обязательно (но на самом деле почти наверняка будет). 9.2/12. –
Я считаю, что макет объектов в памяти - это реализация, а не порядок, обязательно, но объем пространства. В частности, вы, вероятно, столкнетесь с проблемами с выравниванием байтов и так далее, особенно на разных платформах.
Можете ли вы дать нам некоторые сведения о том, что вы пытаетесь сделать?
Я пытаюсь прочитать переменные на уровне байта, отправить их через сокет tcp/ip и поместить их в объект-представитель. Есть ли более простой способ сделать это? (Я хочу, чтобы мой алгоритм был универсальным, независимо от того, какие переменные содержит объект) –
Имейте в виду, что при работе с многомерными массивами они хранятся в Row Major Order.
Порядок переменных не должен меняться, но, как говорили другие, упаковка байтов будет различной. Еще одна вещь, которую следует учитывать, - это утверждение платформы.
Чтобы обойти проблему выравнивания/упаковки байт, большинство компиляторов предлагают какой-либо способ управления процессом. В gcc вы можете использовать __attribute__((__packed__))
и в msvc #pragma pack
.
Мой ответ может быть более уместным для традиционных структур, чем сложные классы. – user64075
Реализации могут делать все, что угодно: P. Однако, поскольку C++ должен привлекать определенные стили программирования, вы найдете детерминированный способ доступа к своим полям для вашей конкретной архитектуры компилятора/платформы/процессора.
Если ваш порядок байтов варьируется в другом компиляторе, мое первое предположение было бы проблемой упаковки байтов. Если вам нужен класс для определенного определенного порядка байтов, сначала найдите директивы «#pragma pack» для вашего компилятора ... вы можете изменить порядок упаковки на что-то менее оптимальное, но детерминированное. Обратите внимание, что этот совет обычно применяется к типам данных POD.
Я работал с тем, что делал это профессионально, и, насколько я мог судить, он работал очень конкретно, потому что он расшифровывал что-то еще в одном закодированном инструменте, поэтому мы всегда знали, как это работает.
Мы также использовали структуры, которые мы указали на адрес памяти, а затем считывали данные через переменные struct, но структуры, в частности, включали упаковку, и мы были на встроенной платформе.
В принципе, вы можете это сделать, пока вы знаете - точно, как все построено на байтовом уровне. (Возможно, вам удастся уйти от знания, когда он будет построен таким же образом, что может сэкономить некоторое время и обучение)
Компилятор C++ не имеет права переупорядочивать переменные в блоке видимости (public, protected и т. Д.). Но разрешено изменять порядок переменных в отдельных блоках видимости.Например:
struct A {
int a;
short b;
char c;
};
struct B {
int a;
public:
short b;
protected:
char c;
};
В приведенных выше переменных переменные в A всегда будут выложены в порядке a, b, c. Переменные в B могут быть выложены в другом порядке, если компилятор выбрал. И, конечно же, существуют требования к выравниванию и упаковке, поэтому при необходимости могут быть «пробелы» между некоторыми переменными.
Похоже, вы хотите сортировать объекты между машинами по TCP/IP-соединению. Вы, вероятно, можете избежать этого, если код был скомпилирован с одним и тем же компилятором на каждом конце, иначе я не уверен. Имейте в виду, что, если платформы могут быть разными, тогда вам, возможно, потребуется учитывать разные термины процессора!
Подумайте об этом подробнее ... Я действительно сделал что-то вроде этого лет назад. Я помню, как определял базовый класс CRemoteable и затем автоматически отправлял содержимое класса (адресованное через этот «указатель») на удаленные машины. Он работал нормально, но на всех машинах работала одна и та же ОС и одна и та же программа. – Gordon
Похоже, что вы реальный хотите, чтобы спросить, как serialize ваши объекты
http://dieharddeveloper.blogspot.in/2013/07/c-memory-layout-and-process-image.html
В середине адресного пространства процесса, существует область зарезервирована для общих объектов. Когда создается новый процесс, диспетчер процессов сначала отображает два сегмента из исполняемого файла в память. Затем он декодирует заголовок ELF программы. Если заголовок программы указывает, что исполняемый файл был связан с общей библиотекой, диспетчер процессов (PM) будет извлекать имя динамического интерпретатора из заголовка программы. Динамический интерпретатор указывает на общую библиотеку, содержащую код компоновщика времени выполнения.
Просьба уточнить, что вы действительно пытаетесь сделать. Вероятно, есть лучший способ. –
Единственный раз, когда объект может обрабатываться как последовательность бит, это когда этот объект имеет тип POD. Во всех остальных случаях обращение с этим способом ведет к неопределенному поведению. – GManNickG
Исследование «Сериализация», «Дестирализация» и «Повышение уровня сериализации». Это поможет вам отправлять объекты через tcp/ip. –