Skip to content

Commit

Permalink
Improve c-object-model
Browse files Browse the repository at this point in the history
  • Loading branch information
selfboot committed Apr 7, 2024
1 parent 206d8e5 commit d7027b6
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions source/_drafts/c-object-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ int main() {
}
```

简单的打印 temp 和 alias 地址,发现两者之间差异挺大。temp 地址是 `0x7fffffffe380`,Basic::alias 是 `0x555555558048`,用 `info target` 可以看到 alias 在程序的 `.data` 内存空间范围 `0x0000555555558038 - 0x000055555555804c` 内。进一步验证了下,`.data`段用于存储已初始化的全局变量和静态变量,注意这里需要是非零初始值。

对于没有初始化,或者初始化为零的全局变量或者静态变量,是存储在 `.bss` 段内的。这个也很好验证,把上面 alias 的值设为0,重新查看内存位置,就能看到确实在 `.bss` 段内了。对于全局变量或者静态变量,**为啥需要分为这两个段来存储,而不是合并为一个段来存储呢**

这里主要是考虑到**二进制文件磁盘空间大小以及加载效率**。在磁盘上,`.data` 占用实际的磁盘空间,因为它**需要存储具体的初始值数据**`.bss`段不占用实际的存储空间,只需要在程序加载时由操作系统分配并清零相应的内存即可,这样可以减少可执行文件的大小。在程序启动时,操作系统可以快速地为`.bss`段分配内存并将其初始化为零,而无需从磁盘读取大量的零值数据,可以提高程序的加载速度。这里详细的解释也可以参考 [Why is the .bss segment required?](https://stackoverflow.com/questions/9535250/why-is-the-bss-segment-required)

静态方法又是怎么实现呢?我们先输出内存地址,发现在 `.text` 代码段,这点和其他成员方法是一样的。不过和成员方法不同的是,第一个参数并不是 this 指针了。在实现上它与普通的全局函数类似,主要区别在于它们的作用域是限定在其所属的类中。

![static method的实现和内存布局](https://slefboot-1251736664.file.myqcloud.com/20240407_c++_object_model_static_method.png)

## 类继承的内存布局

### 不带虚函数的继承
Expand Down

0 comments on commit d7027b6

Please sign in to comment.