Что такое ячейка памяти? - PullRequest
6 голосов
/ 25 марта 2019

Удивительно мало информации появляется поисковой системой. Книга C ++ Concurrency In Action в главе 5 гласит:

В C ++ это все об объектах и ​​местах памяти.

Потом позже,

Каким бы ни был его тип, объект хранится в одной или нескольких ячейках памяти . Каждая такая ячейка памяти является либо объектом (или подобъектом) скалярного типа, таким как unsigned short или my_class*, либо последовательностью смежных битовых полей.

Акцент сделан на том, что напечатано в книге, поэтому ясно, что это фундаментальное понятие, но определения нет.

Итак, что это это? Это универсальная концепция или что-то более узкое в стандарте C ++ 11? Как я должен думать об этом с точки зрения 32-х или 64-х битной архитектуры и регистров процессора? Что это означает, что битовое поле (или, скорее, серия смежных битовых полей ненулевой длины) являются частью одной и той же ячейки памяти? Это последнее утверждение подразумевает, что ячейка памяти может хранить данные произвольной длины.

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

Ответы [ 4 ]

5 голосов
/ 25 марта 2019

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

Как говорит @Caramiriel, long strip of paperсостоит из последовательности байтов.

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

Когда вы получаете structs или объекты, они имеют дело с большими кусками памяти или несколькими кусками памяти, так что вам не нужно знать подробности.

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

3 голосов
/ 25 марта 2019

По данным cppreference.com, место в памяти:

  • объект скалярного типа: арифметический тип (например, int), тип указателя (например, struct timeval*), тип перечисления (например, std::regex_constants::error_type) или недавно выпущенный тип std::nullptr_t - ИЛИ:
  • наибольшая непрерывная последовательность битовых полей ненулевой длины.

… q.v https://en.cppreference.com/w/cpp/language/memory_model#Memory_location

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

2 голосов
/ 25 марта 2019

Общий вид

Память - это «вещь», способная хранить информацию во времени. Вот что такое человеческая память, вот что такое компьютерная память.

В компьютерах - аппаратное обеспечение

Провода (представьте как кабели, так и отпечатанные провода на плате) - это физические объекты, которые передают информацию (так или иначе). Элементы схемы, такие как логические элементы, являются физическими объектами, которые преобразуют информацию. Но они не способны хранить информацию. Память - это аппаратное устройство, которое способно хранить информацию и, конечно же, возвращать эту информацию с течением времени.

В компьютерах организация логической памяти наиболее часто используется в битах и ​​битах. Бит хранит двоичную цифру, которая может иметь значение 0 или значение 1.

Физически, в интегральных схемах немного более-менее транзистор. На жестких дисках это магнитная зона на платане, на компакт-дисках это отражающая или нет зона на диске.

Биты сгруппированы по 8 в байтах. Чтобы «хранить информацию» и «извлекать информацию» из памяти, вам необходимо, чтобы память была адресуемой. То есть вам нужен способ уникальной идентификации области памяти, где вы хотите хранить информацию или откуда ее загружать. Память компьютера адресуется в байтах, что означает, что каждый байт имеет уникальный адрес. Физические адреса байтов памяти являются смежными. Он начинается с адреса 0x0000 и продолжается без пробелов.

В С ++

C ++ не имеет отношения к аппаратному обеспечению. Но логически все одинаково: биты организованы в байтах, память имеет байтовый адрес.

Тип в C ++ определяется размером занимаемой памяти, набором возможных значений и набор возможных операций над данными.

Давайте возьмем std::uint8_t. Его размер 1, что означает, что он занимает всего 1 байт. Поскольку 1 байт имеет 8 битов (в большинстве реализаций), для типа std::uint8_t существует 2 ^ 8 возможных различных значений. Поскольку это просто, значение unsigned char является значением числа в базе 2, образованного битами байта. Например. для битов 0000 0110 значение равно значению числа 0000 0110 (base 2) == 6 (base 10)

Для больших типов данных, например std::int32_t, размер равен 4, поэтому он занимает 4 смежных байта. Это означает 2^32 возможных значений. Вопрос снова в том, как сопоставить эффективные битовые комбинации, которые вы находите в памяти в этих 4 байтах, с целым числом? Это называется схемой кодирования. На аппаратном уровне мы заботимся о маленьких или больших машинах с прямым порядком байтов, которые определяют, в каком порядке мы берем байты. После этого последовательность битов преобразуется в число (или наоборот, число преобразуется в последовательность битов) по схеме кодирования дополнения к двум (обязательным начиная с C ++ 20).

За исключением того, что по архаичным причинам самый маленький адресуемый блок памяти не называется байтом. Это называется char (badum tss).

1 голос
/ 16 июня 2019

В этом ответе приводятся цитаты из стандарта для языковых юристов.Этот ответ должен быть дополнением к существующим ответам.

За [intro.memory] / 3 :

A ячейка памяти является либо объектом скалярного типа, либо максимальной последовательностью смежных битовых полей, все из которых имеют ненулевую ширину. [ Примечание: Различные функции языка, такие как ссылки и виртуальные функции, может включать дополнительные области памяти, которые не доступны для программ, но управляются реализацией.- примечание к концу ] Два или более потоков выполнения могут обращаться к отдельным ячейкам памяти, не мешая друг другу.

[ Примечание: Таким образом, битовое поле и смежные областинебитовые поля находятся в отдельных ячейках памяти и поэтому могут одновременно обновляться двумя потоками выполнения без помех.То же самое относится к двум битовым полям, если одно объявлено в объявлении вложенной структуры, а другое нет, или если два разделены объявлением битового поля нулевой длины, или если они разделены небитовымдекларацияНе безопасно одновременно обновлять два битовых поля в одной и той же структуре, если все поля между ними также являются битовыми полями ненулевой ширины.- примечание конца ]

[ Пример: Класс, объявленный как

struct {
  char a;
  int b:5,
  c:11,
  :0,
  d:8;
  struct {int ee:8;} e;
}

, содержит четыре отдельных области памяти: элемент a ибитовые поля d и e.ee являются отдельными ячейками памяти и могут быть изменены одновременно, не мешая друг другу.Битовые поля b и c вместе составляют четвертую ячейку памяти.Битовые поля b и c не могут быть изменены одновременно, но, например, b и a могут быть.- конец примера ]

Где скалярный тип , возможно, cv-квалифицирован ( [basic.types] / 9 )

  • арифметический тип (целочисленный или с плавающей запятой),

  • тип перечисления,

  • указательтип

  • тип указателя на элемент или

  • std::nullptr_t.

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