Как осуществляется доступ к членам структуры C из памяти во время выполнения? - PullRequest
2 голосов
/ 09 января 2012

У нас есть структура в C, скажем

struct info{
    int no;
    char first_name[20];
    char last_name[20];
    char status;
}

Во время выполнения, когда мы пытаемся получить доступ к этим элементам по их имени, скажем info_var.no или info_var.first_name, или мы используем указатель на структуру,info_ptr->no или info_ptr->first_name, как осуществляется доступ к этим отдельным элементам?

Я имею в виду, что структура будет сохраняться как член за элементом вместе с некоторыми необходимыми дополнениями, но как работает среда выполнения или, возможно, компилятор, еслизамена происходит во время компиляции, доступ к этим отдельным элементам по их имени?

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

Ответы [ 4 ]

5 голосов
/ 09 января 2012

В C работа выполняется компилятором.Он компилирует элементы данных структур в смещения памяти и применяет их к базовому адресу структуры.

Нет динамического поиска имен переменных, как, например, в Python

2 голосов
/ 09 января 2012

Существует большая разница между доступом к структуре напрямую и через указатель.

Если вы обращаетесь к ней напрямую, код получит прямой доступ к адресу памяти, используя упрощенный синтаксис ассемблера, фиктивной архитектуры.Приведенные ниже примеры обращаются к члену status, который хранится со смещением 44 в структуре:

MOVB  varno+44, reg2

С другой стороны, если вы обращаетесь к нему через локальный указатель, указатель обычно сохраняетсяв реестре.Таким образом, код будет выглядеть примерно так:

MOVB  44[reg1], reg2

В худшем случае, если сам указатель является глобальным указателем, тогда код должен сначала прочитать значение указателя:

MOVL  info_ptr, reg1
MOVB  44[reg1], reg2

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

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

2 голосов
/ 09 января 2012

Доступ по указателю или объекту не имеет значения, фактически info_ptr->no эквивалентно (*info_ptr).no.

Фактический доступ к элементу зависит от компилятора.

Скажем, у вас есть:

class A
{
public:
   char c;
   int x;
   A() {};
};

Ниже приведен код доступа:

   A a;
004113BE  lea         ecx,[a] 
004113C1  call        A::A (4110E1h) 
   int y = a.x;
004113C6  mov         eax,dword ptr [ebp-8] 
004113C9  mov         dword ptr [y],eax 

Таким образом, компилятор в этом случае генерирует двоичный файл, зная, где x хранится в памяти относительно a -это 8 байтов в экземпляр A.Это из-за отступов.

РЕДАКТИРОВАТЬ: Я только что увидел, что вопрос о C. Независимо, должно быть то же самое:).

0 голосов
/ 09 января 2012

Каждое поле имеет заранее определенное смещение от начала struct.Смещение определяется во время компиляции.Машинный код просто добавляет смещение поля для перехода от адреса struct к адресу поля.

Когда вы говорите «Во время выполнения, когда мы пытаемся получить доступ к этим элементам по их имени», оноважно отметить, что все работы, связанной с именем, выполняются во время компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...