C语言-内存

本文最后更新于:1 年前

综合

  • 全局变量默认初始值为0

  • 局部变量未规定默认初始值

  • 栈是针对线程来说的,每个线程都拥有一个栈,如果一个程序包含了多个线程,那么它就拥有多个栈

    发生函数调用时会将相关数据(包括局部变量、局部数组、形参、寄存器、冗余数据等)压入栈中,函数调用结束会释放这一部分内存

    递归函数内部嵌套了对自身的调用,除非等到最内层的函数调用结束,否则外层的所有函数都不会调用结束,所以很容易出现栈溢出。

  • 栈 使用的内存大小在编译时决定

    在 VC/VS 下,默认是 1M,

    在 C-Free 下,默认是 2M,

    在 Linux GCC 下,默认是 8M

虚拟地址范围

32位编译模式

一个指针或地址占用4个字节的内存,理论上能够访问的虚拟内存空间大小为 2^32 = 0X100000000 Bytes,即4GB,有效虚拟地址范围是 0 ~ 0XFFFFFFFF。

64位编译模式

一个指针或地址占用8个字节的内存,共有64位,理论上能够访问的虚拟内存空间大小为 2^64。

Windows 和 Linux 都对虚拟地址进行了限制,仅使用虚拟地址的低48位(6个字节),总的虚拟地址空间大小为 2^48 = 256TB。

2^64 是一个很大的值,几乎是无限的,就目前的技术来讲,不但物理内存不可能达到这么大,CPU的寻址能力也没有这么大,实现64位长的虚拟地址只会增加系统的复杂度和地址转换的成本

内存对齐

将一个数据尽量放在一个步长之内,避免跨步长存储。

在32位编译模式下,默认以4字节对齐;在64位编译模式下,默认以8字节对齐。

对于全局变量,GCC在 Debug 和 Release 模式下都会进行内存对齐,而VS只有在 Release 模式下才会进行对齐。

而对于局部变量,GCC和VS都不会进行对齐,不管是Debug模式还是Release模式。

1
2
3
4
#pragma pack(1)
//范围内代码按1字节方式对齐
#pragma  pack()
//注意作用域,及时解除