C++ 内存笔记

堆栈

  • 堆 程序员自由挥霍的一大部分内存
  • 栈 系统自动管理的一小部分内存

虚拟内存

当今的操作系统都会给每一个进程分配独立的虚拟地址空间

虚拟内存是计算机系统内存管理的一种技术,它使得应用程序认为它拥有连续的可用内存,而实际上,它通常是被分割成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上。在需要时进行数据交换。

内存地址

  • 函数 字符串常量
  • 静态变量(函数类static变量 文件类的static变量 全局变量)
  • 利用malloc分配的内存区域
  • 自动变量

函数自身和字符串常量被配置在内存里相邻的地址上(只读区域)

静态变量

静态变量是从程序启动到运行结束为止持续存在的变量,因此静态变量总是在虚拟地址空间上占有固定区域。

包括全局变量,文件内static变量和指定static的局部变量。因为这些变量的有效作用域各不相同,所以编译和链接时具有不同的意义,但是运行的时候都是以相似的方式呗使用。

自动变量

保存在栈,一旦函数执行结束,自动变量的内存区域就会被释放

自动变量属于连接器管辖以外的对象,因为自动变量的地址是在运行时决定。

内存分配

malloc()根据指定的只存来分配内存块,它返回指向内存块初始位置的指针,经常被用于动态分配结构体的内存区域,分配不足返回NULL。

//void*标识泛型指针,可以赋给任何类型的指针变量
void* malloc(size_t size);

//分配1000个字节的堆空间,返回第一个字节的地址
char *p = malloc(1000);

//释放第一个字节的地址为p的堆
free(p);

堆栈区别

int *func(void)
{
    int a ;
    int *p = malloc(4);

    //错误,func函数在执行完成之后,所在的栈的空间被释放,a也被释放
    return &a;

    //正确,p分配的地址在堆上面,不会随着函数的结束而释放,只有自己释放或者在程序结束后释放。
    return p;
}

内存操作函数

//从source指向的位置直接复制num个字节的值到destination指向的内存块。
void * memcpy ( void * destination, const void * source, size_t num );

//从source指向的位置复制num个字节的值到destination指向的内存块。复制操作的发生就好像使用了中间缓存,允许destination和source重叠。
void * memmove ( void * destination, const void * source, size_t num );

//将ptr指向的内存块的前num个字节设置为特定的值value(被解释为一个unsigned char类型的值)
void * memset ( void * ptr, int value, size_t num );

//在ptr指向的内存块的前num个字节中搜索value值得第一次出现(被解释为一个unsigned char类型的值),并返回指向该值的指针。
const void * memchr ( const void * ptr, int value, size_t num );
      void * memchr (       void * ptr, int value, size_t num );

//将ptr2指向的内存块的签num个字节与ptr2指向的内存块的前num个字节进行比较,如果它们都相符合则返回0,反之则返回一个指示其中一个较大的非零值。
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

在各个块之前加上一个管理区域,通过管理区域构建一个链表。malloc遍历链表寻找空的块,如果发现尺寸正好能够满足使用的块,就分割出来将其变成使用中的块,并且向应用程序返回紧邻管理区域的后面区域的地址。

free将管理区域的标识改写成空块,顺便也将上下空的块合并成一个块。这样可以防止块的碎片化。

如果不存在足够大的空块,就请求操作系统对空间进行扩容。(unix系统下用brk系统调用)

调用free后,对应的内存区域不会立刻被破坏,而是保留着原来的值,知道某个地方执行malloc(),随着当前内容被重新分配,内容才开始被破坏。

只要使用malloc的内存管理,就无法根本回避碎片化问题。

calloc = malloc + memset

realloc扩展内存区域,如果传递的区域后面有足够大小的空闲区域,就分配给其他新的空间,然后将内容复制过去,如果常用realloc扩展内存区域,而后面没有足够的空间,就会影响运行效率。

不断对内存进行分配,释放的操作会引起内存碎片化。解决的办法是一次性扩容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值