1.动态内存分配

 C语言中的一切操作都是基于内存的
  变量和数组都是内存的别名,如何分配这些内存由编译器在编译期间决定
  定义数组的时候必须指定数组长度,而数组长度是在编译期就必须决定的
内存的分配与释放:
malloc和free:malloc和free用于执行动态内存分配和释放
 malloc所分配的是一块连续的内存,以字节为单位,并且不带任何的类型信息
 free用于将动态内存归还系统

void\* malloc(size_t size);
void free(void\* pointer);

malloc实际分配的内存可能会比请求的稍微多一点,但是不能依赖于编译器的这个行为;

当请求的动态内存无法满足时malloc返回NULL;

当free的参数为NULL时,函数直接返回

云平台内存超分方法_c/c++

calloc和realloc :

 void* calloc(size_t num, size_t size);
 void* realloc(void\* pointer, size_t new_size);

  calloc的参数代表所返回内存的类型信息,calloc会将返回的内存初始化为0
  realloc用于修改一个原先已经分配的内存块大小;
  在使用realloc之后应该使用其返回值,当pointer的第一个参数为NULL时,等价于malloc

2.程序中的 栈、堆、静态存储区

栈:函数调用的使用

 栈是现代计算机程序里最为重要的概念之一

 栈在程序中用于维护函数调用上下文,没有栈就没有函数,没有局部变量

 栈保存了一个函数调用所需的维护信息:

  函数参数,函数返回地址;局部变量;函数调用上下文

云平台内存超分方法_c/c++_02


堆:内存的动态申请和归还

 堆是程序中一块巨大的内存空间,可由程序自由使用

 堆中被程序申请使用的内存在程序主动释放前将一直有效

 系统对堆空间的管理方式:空闲链表法,位图法,对象池法等等

云平台内存超分方法_云平台内存超分方法_03


静态存储区:保存全局变量和静态变量

 程序静态存储区随着程序的运行而分配空间,直到程序运行结束

  在程序的编译期静态存储区的大小就已经确定

  程序的静态存储区主要用于保存程序中的全局变量和静态变量

  与栈和堆不同,静态存储区的信息最终会保存到可执行程序中

3.程序的内存布局

代码在可执行程序中的对应关系

云平台内存超分方法_c/c++_04


文件布局在内存中映射

云平台内存超分方法_静态存储_05


各个段的作用

 堆栈段在程序运行后才正式存在,是程序运行的基础

 .bss段存放的是未初始化的全局变量和静态变量

 .text段存放的是程序中的可执行代码

 .data段保存的是那些已经初始化了的全局变量和静态变量

 .rodata段存放程序中的常量值,如字符串常量

程序术语对应关系
 静态存储区通常指程序中的.bss和.data段
 只读区通常指程序中的.rodata段
 局部变量所占空间为栈上空间
 动态空间为堆中的空间
 程序可执行代码存放于.text段

4.野指针和内存操作分析

野指针
 野指针通常是因为指针变量中保存的值不是一个合法的内存地址而造成的
  野指针不是NULL指针,是指向不可用内存的指针
  NULL指针不容易用错,因为if语句很好判断一个指针是不是NULL
野指针的由来
 局部指针变量没有被初始化
  使用已经释放过后的指针
  指针所指向的变量在指针之前被销毁
非法内存操作
 结构体成员指针未初始化;没有为结构体指针分配足够的内存
 内存分配成功,但并未初始化
 数组越界
 内存泄露
 多次指针释放
 使用已释放的指针
C语言中的规则
 用malloc申请了内存之后,应该立即检查指针值是否为NULL,防止使用值为NULL的指针
 牢记数组的长度,防止数组越界操作,考虑使用柔性数组
 动态申请操作必须和释放操作匹配,防止内存泄露和多次释放
 free指针之后必须立即赋值为NULL


转载于:https://blog.51cto.com/yinsuifeng/2174056