命名空间
变体
操作

内存模型

来自 cppreference.com
< c‎ | 语言

为 C 抽象机的目的定义了计算机内存存储的语义。

C 程序可用的数据存储(内存)是一个或多个连续的字节序列。内存中的每个字节都有一个唯一的地址

内容

[编辑] 字节

字节是内存中最小的可寻址单元。它被定义为一个连续的位序列,足够大到容纳基本执行字符集需要是单字节的 96 个字符)中的任何成员。C 支持大小为 8 位或更大的字节。

类型 charunsigned charsigned char 使用一个字节来进行存储和值表示。字节中的位数可以通过 CHAR_BIT 来获取。

有关使用字节表示其他基本类型的值(包括大端和小端内存布局)的信息,请参见对象表示

[编辑] 内存位置

内存位置

  • 一个标量类型(算术类型、指针类型、枚举类型)的对象
  • 或最长的连续位域序列(长度不为 0)
struct S
{
    char a;     // memory location #1
    int b : 5;  // memory location #2
    int c : 11, // memory location #2 (continued)
          : 0,
        d : 8;  // memory location #3
    struct
    {
        int ee : 8; // memory location #4
    } e;
} obj; // The object 'obj' consists of 4 separate memory locations

线程和数据竞争

执行线程是程序中的一个控制流,从thrd_create或其他方式调用顶级函数开始。

任何线程都可能访问程序中的任何对象(具有自动和线程局部存储持续时间的对象仍然可以通过指针被其他线程访问)。

不同的执行线程始终被允许并发访问(读取和修改)不同的内存位置,而不会产生干扰,也不需要同步要求。(注意,如果在两个非原子位域之间声明的所有成员也都是(非零长度)位域,则无论这些中间位域的大小如何,并发更新同一个结构中的两个非原子位域是不安全的)

当一个表达式的求值写入一个内存位置,而另一个求值读取或修改同一个内存位置时,这两个表达式被称为冲突。如果程序有两个冲突的求值,则该程序存在数据竞争,除非以下情况之一成立:

如果发生数据竞争,程序的行为将是未定义的。

(特别地,mtx_unlock与...同步的,因此,它发生在另一个线程对同一个互斥锁的mtx_lock之前,这使得可以使用互斥锁来防止数据竞争)

内存顺序

当一个线程从一个内存位置读取一个值时,它可能看到初始值、在同一个线程中写入的值或在另一个线程中写入的值。有关线程写入的值对其他线程可见的顺序的详细信息,请参见memory_order

(自 C11 开始)

[编辑] 参考文献

  • C23 标准 (ISO/IEC 9899:2024)
  • 3.6 字节 (p: TBD)
  • 3.14 内存位置 (p: TBD)
  • 5.1.2.4 多线程执行和数据竞争 (p: TBD)
  • C17 标准 (ISO/IEC 9899:2018)
  • 3.6 字节 (p: TBD)
  • 3.14 内存位置 (p: TBD)
  • 5.1.2.4 多线程执行和数据竞争 (p: TBD)
  • C11 标准 (ISO/IEC 9899:2011)
  • 3.6 字节 (p: 4)
  • 3.14 内存位置 (p: 5)
  • 5.1.2.4 多线程执行和数据竞争 (p: 17-21)
  • C99 标准 (ISO/IEC 9899:1999)
  • 3.6 字节 (p: 4)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 1.6 术语定义

[编辑] 另请参见

C++ 文档 中的 内存模型