Как определить структуру памяти структуры? - PullRequest
3 голосов
/ 20 марта 2012

Предположим, у меня есть следующая структура (в C):

struct my_struct {
  int foo;
  float bar;
  char *baz;
};

Если у меня теперь есть переменная, скажем

struct my_struct a_struct;

Как я могу узнать, как поля этой структуры будут расположены в памяти? Другими словами, мне нужно знать, какими будут адреса a_struct.foo, a_struct.bar и a_struct.baz. И я не могу сделать это программно, потому что на самом деле я кросс-компилирую на другую платформу.

ПОЯСНЕНИЯ

Спасибо за ответы, но я не могу сделать это программно (то есть с макросом offsetof или с небольшой тестовой программой), потому что я кросс-компиляция и мне нужно знать, как будут выровнены поля на платформе target . Я знаю, что это зависит от реализации, вот и весь смысл моего вопроса. Я использую GCC для компиляции, ориентируясь на архитектуру ARM.

В конце концов мне нужно иметь возможность выгружать память с целевой платформы и анализировать ее с помощью других инструментов, таких как библиотека struct Python. Но для этого мне нужно знать, как были разбиты поля.

Ответы [ 4 ]

4 голосов
/ 20 марта 2012

В общем, это зависит от реализации.Это зависит от таких вещей, как компилятор, настройки компилятора, платформа, на которой вы компилируете, размер слова и т. Д. Вот предыдущая тема SO по этой теме: C struct memory layout?

Если вы выполняете кросс-компиляцию, я думаю, что конкретный макет будет отличаться в зависимости от того, для какой платформы вы компилируете.Я бы посоветовался со ссылками на ваш компилятор и платформу.

2 голосов
/ 28 июля 2018

В пакете dwarves есть программа pahole (Poke-A-Hole), которая создаст отчет, показывающий структуры вашей программы, а также маркеры, показывающие, где и насколько большой отступ.

0 голосов
/ 20 марта 2012

Я думаю, у вас есть два варианта.

Первый - использовать __attribute__((packed)) после объявления структуры.Это гарантирует, что каждому члену будет выделен именно тот объем памяти, который требуется его типу.

Другой - проверить вашу структуру и использовать правила выравнивания (n-байтовая переменная базового типа должна быть n-выровнено по байту), чтобы выяснить расположение.

В вашем примере, в любом случае каждая переменная-член займет 4 байта, а структура будет занимать 12 байтов в памяти.

0 голосов
/ 20 марта 2012

Один хакерский способ увидеть представление в памяти того, что внутри него, - привести структурный указатель к указателю на символ, а затем распечатать все символы, например:

struct my_struct s;
s.foo = MAX_INT;
s.bar = 1.0;
s.baz = "hello";

for (int i = 0; i < sizeof(s); i++) {
  char *c = ((char*)&s) + i;
  printf("byte %d: 0x%02x\n", i, *c);
}

Это неЯвно покажу вам границы, вам придется вывести это из дампа.Вы также захотите использовать типы с явно заданным размером, например uint32 вместо unsigned int

...