C/C++内存管理

简介: 1. 静态内存   静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源。程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用完毕时,系统会自动释放所占用的内存空间。

 1. 静态内存

  静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源。程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用完毕时,系统会自动释放所占用的内存空间。变量的分配与释放,都无须程序员自行考虑。

  eg:基本类型,数组

2. 动态内存

  用户无法确定空间大小,或者空间太大,栈上无法分配时,会采用动态内存分配。用malloc或者new申请任意多少的内存,程序员自己负责在何时用free或者delete手动释放内存。只用malloc或new分配的内存在堆里。

3.静态内存和动态内存的区别

  (1) 静态内存分配在编译时完成,不占用CPU资源; 动态内存分配在运行时,分配与释放都占用CPU资源。

  (2) 静态内存在栈(stack)上分配; 动态内存在堆(heap)上分配。

  (3) 动态内存分配需要指针和引用类型支持,静态不需要。

  (4) 静态内存分配是按计划分配,由编译器负责; 动态内存分配是按需分配,由程序员负责。

4.内存分配方式

  虚拟内存结构:

   

:这里谈的分配,都是指在虚拟内存中的分配。实际的分配需要做的是将虚拟地址映射到物理地址(段页式存储管理)。

内存分配方式一共有三种:

  (1)从静态存储区域分配(全局变量,静态变量,在虚拟内存的数据段

  内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,例如,全局变量,静态变量

  (2)在上创建(局部变量,在虚拟内存的栈,属于静态内存

  在执行函数时,函数内局部变量的存储单元都可以在上创建,函数执行结束后这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限

  (3)在上分配,亦称动态内存分配(malloc或者new申请,在虚拟内存的堆里,即在“空洞”里,属于动态内存)

  程序在运行的时候用malloc或者new申请任意多少的内存,程序员自己负责在何时用free或者delete手动释放内存。动态内存的生存期由程序员决定,使用非常灵活,但是问题也多。

5.内存释放问题

  (1)静态存储区域以及创建的栈,在函数执行完以后,出栈销毁,这个过程会自动释放静态分配的内存,不需要程序员手动操作;

  (2)而动态分配的内存,实际是在堆上,系统没法自动释放堆上的内存,需要程序员手动写free或者delete函数来告诉系统需要释放堆上哪个位置的内存;

6.常见的内存错误及对策

  (1)内存尚未分配成功,却使用了它;

  解决办法:在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口使用assert(p != NULL) 进行检查,如果是用malloc或者new来申请的,应该用if (p == NULL)或者 if (p != NULL) 来进行防错处理。

  (2)内存分配虽然成功,但是尚未初始化就引用它;

  错误原因:一是没有初始化的观念,二是误以为内存的缺省初值全为零,导致引用初值错误(如数组)。

  解决办法:内存的缺省初值是什么并没有统一的标准,尽管有些时候为零值,但是宁可信其有,不可信其无,无论以何种方式创建数组,都要赋初值。

int *p1,*p2;
int a=100,b=60;
p1=&a;
p2=&b;
//或者*p1=a;*p2=b;
printf("%d,%d\n",*p1,*p2);//100,60

  (3)内存分配成功并初始化,但是超过了内存的边界;

  这种问题常出现在数组越界,写程序是要仔细。

  (4)忘记释放内存,造成内存泄露

  含有这种错误的函数每次被调用都会丢失一块内存,开始时内存充足,看不到错误,但终有一次程序死掉,报告内存耗尽。

7.内存管理需要遵循的规则

  (1)用malloc 或者 new 申请内存之后,应该立即检查指针值是否为 NULL ,防止使用指针值为NULL的内存;

  (2)不要忘记数组和动态内存赋初值,防止未被初始化的内存作为右值使用;

  (3)避免数组或者指针下标越界,特别要当心“多1”或者“少1”的操作;

  (4)动态内存的申请与释放必须配对,防止内存泄露;

  (5)用free或者delete释放了内存之后立即将指针设置为NULL,防止产生“野指针”。

8.动态内存管理操作

  8.1动态内存分配

//函数说明
#include<stdio.h>
void *malloc(size_t size);
void *calloc(size_t nmemb,size_t size);

  (1)malloc的参数size表示分配的内存空间的大小,单位是字节Byte。

  (2)calloc的参数nmemb表示分配的内存空间占的数据项数目,参数size表示一个数据项的大小,单位是字节Byte。也就是说calloc分配的是nmemb X size大小的内存空间。

两者的区别是calloc将初始化所分配的内存空间,把所有位设置为0。

  (3)调用成功返回分配内存的地址,失败返回null。

  8.2动态内存释放

//函数说明
#include<stdio.h>
void free(void *ptr);

  动态内存示例:

#include<stdio.h>
#include<string.h>
char *upcase(char *inputstring);
int main(void)
{
  char *str1;
  str1=upcase("Hello");
  printf("str1 = %s \n",str1);
  free(str1);
  return 0;

} 
//子函数中动态分配的内存的指针返回到主函数中
char *upcase(char *inputstring)
{
  char *newstring;
  int counter;
  if(!(newstring=malloc(strlen(inputstring)+1))//为newstring分配动态内存,长度为strlen(inputstring)+1
  {
    printf("Error allocate memory!");
    exit(255);
  }
  
  strcpy(newstring,inputsreing);
  for(counter=0;counter<strlen(newstring);counter++)
  {
    if(newstring[counter]>=97 && newstring[counter]<=122)
    {
      newstring[counter]-=32;
    }
  }
  return newstring;
}
目录
相关文章
|
1月前
|
存储 Java 编译器
C++:内存管理|new和delete
C++:内存管理|new和delete
|
1月前
|
存储 算法 编译器
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
46 0
|
1月前
|
IDE Linux 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(一)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
85 0
|
2天前
|
存储 人工智能 程序员
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
29 1
|
29天前
|
存储 Linux C语言
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
|
29天前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
101 0
|
30天前
|
存储 Linux 程序员
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
73 0
|
30天前
|
算法 Java C++
【C/C++ 内存知识扩展】内存不足的可能性分析
【C/C++ 内存知识扩展】内存不足的可能性分析
12 0
|
30天前
|
存储 算法 Linux
深入理解Linux内存管理brk 和 sbrk 与以及使用C++ list实现内存分配器
深入理解Linux内存管理brk 和 sbrk 与以及使用C++ list实现内存分配器
35 0
|
1月前
|
缓存 Linux iOS开发
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
65 1