什么是存储位置?

时间:2019-03-25 15:06:03

标签: c++ c++11 memory

令人惊讶的是,搜索引擎提供的信息很少。本书 C ++并发运行在第5章中指出:

  

在C ++中,一切都与对象和内存位置有关。

然后,

  

无论类型如何,对象都存储在一个或多个内存位置中。每个此类存储位置都是标量类型的对象(或子对象),例如unsigned shortmy_class*或一系列相邻的位字段。

重点如书中所述,很明显是一个基本概念,但没有定义。

那么,是什么?它是通用概念还是C ++ 11标准中更狭义的定义?在32位和64位架构以及CPU寄存器方面,我应该如何考虑?位字段(或更确切地说,一系列非零长度的相邻位字段)是同一存储位置的一部分是什么意思?最后一条语句暗示一个内存位置可以存储任意长度的数据。

如果以上引文的定义,那么我希望能看到有助于提高对这一概念的直观理解的讨论。

4 个答案:

答案 0 :(得分:5)

体系结构通常无关紧要,因为对于大多数正在使用的CPU,可寻址位置以byte s为单位。

正如@Caramiriel所说,long strip of paper由一系列字节组成。

有时候,您需要对它们进行较大的处理,比如说uint32_t一次处理4个字节。

当您访问struct或对象时,它们将处理更大的内存块或多个内存块,因此您不必了解详细信息。

但是,我认为C语言以及C++可以移植到各种体系结构中,其中最小的可寻址内存单元可以大于(或小于)一个字节。

答案 1 :(得分:2)

根据cppreference.com,内存位置为:

  • 标量类型的对象:算术类型(例如int),指针类型(例如struct timeval*),枚举类型(例如std::regex_constants::error_type)或最近创建的{ {1}}类型–或:
  • 最大的非零长度位域连续序列。

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

…直观上,这就是您在“内存位置”中找到的内容–当std::nullptr_t产生指向内存中有效地址的指针时,变量variable的内容可能是什么。

答案 2 :(得分:2)

一般视图

内存是一种能够随时间存储信息的“事物”。那就是人类的记忆,那就是计算机的记忆。

在计算机中-硬件

电线(考虑电路板上的电缆和压印电线)是(以某种方式)传输信息的物理实体。诸如逻辑门之类的电路元件是转换信息的物理实体。但是它们不能存储信息。内存是一种能够存储信息的硬件设备,当然,它会随着时间的流逝回馈信息。

在计算机中,最常用的逻辑内存组织是按位排列。一个位存储一个二进制数字,该二进制数字可以具有值0或值1

从物理上讲,在集成电路中,一位或多或少是一个晶体管。在硬盘上,它是平台上的磁性区域,在CD上,它是磁盘上的反射区域,而不是反射区域。

位按8个字节分组。为了从存储器中“存储信息”和“检索信息”,您需要存储器是可寻址的。即您需要一种方法来唯一标识要在其中存储信息或从中加载信息的内存位置。计算机存储器是按字节寻址的,这意味着每个字节都有一个唯一的地址。存储器字节的物理地址是连续的。它从地址0x0000开始,连续进行,没有任何间隙。

在C ++中

C ++本身与下面的硬件无关。但是从逻辑上讲,它们是相同的:以字节为单位组织位,以字节为单位寻址内存。

C ++中的类型是由它所占用的内存大小以及可能的值集定义的 以及可能对数据进行的一组操作。

让我们来std::uint8_t。它的大小为1,这意味着它仅占1个字节。因为1个字节有8位(在大多数实现中),所以std::uint8_t类型有2 ^ 8个可能的不同值。因为很容易,所以unsigned char的值是由2个字节的位组成的以2为底的数字的值。例如。对于0000 0110位,该值是数字0000 0110 (base 2) == 6 (base 10)

的值

对于较大的数据类型,例如std::int32_t,大小为4,因此它占用4个相邻字节。这意味着2^32个可能的值。问题又是如何将在这四个字节中在内存中找到的有效位模式映射为整数?那就是所谓的编码方案。在硬件级别上,我们关心的是字节序少或大的机器,这些机器决定了字节取的顺序。之后,通过二进制补码(自C ++ 20起强制使用)将位序列转换为数字(或相反,将数字转换为位序列)。

除了出于古老的原因,最小的可寻址存储单元不称为字节。它称为char(巴杜姆tss)。

答案 3 :(得分:1)

此答案提供了语言律师标准的引语。该答案是对现有答案的补充。

[intro.memory]/3

  

内存位置是标量类型的对象或最大值   相邻位域的序列都具有非零宽度。 [注意:   语言的各种功能,例如参考和虚拟   功能,可能涉及不属于的其他内存位置   程序可访问,但由实施管理。   — 尾注]可以访问两个或多个执行线程   分开的内存位置,而不会互相干扰。

     

[注意:因此,一个位字段和一个相邻的非位字段位于   单独的内存位置,因此可以同时更新   通过两个执行线程而不会受到干扰。同样适用于   两个位域(如果在嵌套的struct声明中声明了一个)   另一个则不是,或者两者之间用零长度分隔   位域声明,或者如果它们被非位域分隔   宣言。同时更新两个位字段是不安全的   如果它们之间的所有字段也是的位字段,则使用相同的结构   非零宽度。 — 尾注]

     

[示例:声明为

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

包含四个单独的存储位置:成员a和位字段   de.ee分别是独立的存储位置,可以修改   同时并不会互相干扰。位域b   和c一起构成第四存储位置。位域   bc不能同时修改,但是ba对于   例如,可以。 — 最终示例]

标量类型可能是cv限定([basic.types]/9

  • 算术类型(整数或浮点数)

  • 枚举类型

  • 指针类型

  • 成员指针类型,或

  • std::nullptr_t