白话C++系列(5)

C++内存管理

什么是内存管理?

思考:内存的本质是什么?---->资源

思考:谁掌管内存资源? ---->操作系统

思考:我们能做什么?  ---->申请/归还

申请/归还内存资源就是内存管理

C++中如何进行内存的申请和释放?

申请  --->使用运算符new

释放  --->使用运算符delete

即:

申请内存:int *p = new int;

释放内存:  delete p;

这样就申请和释放一个内存或是某一种类型的内存

思考:如何申请和释放块内存呢?

int *arr = new int[10];  //申请了10个整型的块内存

delete []arr;    //释放块内存

思考:申请内存是否一定就能申请成功呢?显然,不一定!!

因此,编码时,就要对可能的申请内存失败进行处理

int *p = new int[1000];

if(NULL == p)

{

//内存分配失败

}

释放内存后,要将相应的指针赋值为空,即

delete p;                   delete []p;

p = NULL;                 p = NULL;

如果将释放后的指针不置为空,那么当前的这个指针还是指向相应的那块内存,如果我们不小心又调用了一次delete,那么就会使得同一块内存被重复回收,一旦被重复回收,计算机就会出现异常。

小结:

1) 使用new申请内存,使用delete释放内存

2) 申请内存时需要判断是否申请成功,释放内存后需要将指针置为空

3) new和delete要配套使用

最后看一个实例:

在堆中申请100个char类型的内存,拷贝Hello imooc字符串到分配的堆中的内存中,打印字符串,最后释放内存。

完整可执行程序:

#include <string.h>
#include <iostream>
using namespace std;
int main(void)
{
    char *str = new char[100];//在堆中申请100个char类型的内存
    strcpy(str, "Hello imooc"); //拷贝Hello C++字符串到分配的堆中的内存中
    cout<<str<<endl;//打印字符串
    delete []str;//释放内存
    str=NULL;
    return 0;
}
时间: 2024-12-18 00:44:48

白话C++系列(5)的相关文章

白话C++系列(10)--对象的生离死别

对象的生离死别 思考:实例化的对象是如何在内存中存储的? 思考:类中的代码又是如何存储的? 思考:数据和代码之间又有怎样的关系呢? 带着这些问题,先学习一下对象的结构 对象结构 要想为大家说清对象是如何存储的,就必须先为大家介绍一下内存中按照用途被划分的5个区域. 栈区的特点是内存由系统进行控制,无论是分配还是回收都不需要程序员关心: 如果我们使用new来分配一段内存,那么这段内存会分配在堆区,最后我们自己必须用delete回收这段内存: 全局区用来存储全局变量和静态变量: 常量区用来存放一些字

白话C++系列(7)

初始字符串类型 思考如下一个问题:我们平时在编码过程中,适用频繁而操作又比较繁琐的数据都有哪些呢? 对于基本数据类型(int.char.float.double.bool),我们虽用的比较频繁,但操作起来还是比较方便的,基本令人满意.只有char数组,也就是通常所说的字符串,我们平时用的比较频繁,但操作上却缺乏一种简单有效的手段,往往只能用一系列的函数来应付,如strlen.strcat.strcmp.strcpy.strncmp.strncpy等,用得多了就觉得特别麻烦,有时会令人抓狂.为了解

白话C++系列(8)

属性封装的艺术 数据的封装 下面看一个例子,例子中定义了一个学生的类,类中含有两个数据成员,一个是姓名,一个是年龄 上面的代码给人一种相当亲切,有一种似曾相识的感觉,那是因为之前我们一直都是这么用的,而且用的也很爽.但是,这样用是有问题的,最大的问题是它违背了面向对象的知道思想. 那么面向对象的基本思想是什么呢? 面向对象的核心就是以对象为中心,具体来说,就是要以谁做什么来表达程序的逻辑,体现在代码层面上,就是将所有的数据操作转换为成员函数的调用.换句话说,对象在程序中的所有行为都通过调用自己的

白话C++系列(4)

C++函数新特性 函数参数默认值 有如下函数声明: voidfun(int i, int j = 10, int k = 20);√ voidfun(int i, int j = 10, int k) ;X 注意:有默认参数值的参数必须在参数表的最右端 在函数声明时可以带上参数默认值,而在定义时,不建议带上参数默认值.如果在函数定义的时候也协商函数参数默认值,则实际编译时,有的编译器能够编译通过,而有的编译器编译不会通过. 示例: #include <iostream> #include<

白话LINQ系列2---以代码演进方式学习LINQ必备条件

今天我们通一个简单的示例代码的演进过程,来学习LINQ必备条件:隐式类型局部变量:对象集合初始化器:委托:匿名函数:lambda表达式:扩展方法:匿名类型.废话不多说,我们直接进入主题. 一.实现要求 1.获取全部女生: 2.对满足要求的结果按年龄排序: 3.获取结果的前两名: 4.对获取结果计算平均年龄: 5.输出结果信息,包含姓名.性别.年龄: 说明:学生类为Student(包含学生完整信息),输出结果类为:StudentInfo(包含我们关心的信息,后面将演示它是如何消失的).在此我们不讨

白话C++系列(9)

精彩的类外定义 类内定义 问题:什么是类内定义? 将成员函数的函数体写在类的内部的方式称为类内定义.比如下面的Student的类,我们可以看到,在定义成员函数的时候,包括每个成员函数用于实现的函数体,都在类的内部. 类内定义与内联函数的关系 类内定义的成员函数,编译器会将其优先编译为内联函数,但是对于复杂的成员函数无法编译成内联函数的,就编译成普通的函数. 类外定义 所谓类外定义是指成员函数的函数体写在类的外面.具体来讲,类外定义又分为以下两种形式: 所谓同文件类外定义,是指成员函数虽然定义在类

排序算法系列——插入排序

记录学习点滴,菜鸟成长记 接触算法是研究生期间做项目时,需要编写一些诸如GA.QGA的时候,第一次使用“排序”还是用的Java自带的Comparator接口.后来买了<算法导论>来看,发现果然所有知识都是有专业壁垒的,简单的一个问题尽然蕴藏着如此多的思想,发现此简直欣喜无比,遂决定要好好研究研究.只有深入后才发现,原来算法的不仅仅是按照逻辑顺序写个程序那么简单,好的算法要考虑到方方面面,最简单的时间复杂度就够我学习很长时间了. 将自己学习排序算法的一些理解和感悟记录于此,方便自己温故而知新.

MongoDB资料汇总(转)

原文:MongoDB资料汇总 上一篇Redis资料汇总专题很受大家欢迎,这里将MongoDB的系列资料也进行了简单整理.希望能对大家有用. 最后更新时间:2013-04-22 1.MongoDB是什么 MongoDB介绍PPT分享 MongoDB GridFS介绍PPT两则 初识 MongoDB GridFS MongoDB GridFS 介绍 一个NoSQL与MongoDB的介绍PPT MongoDB:下一代MySQL? 写给Python程序员的MongoDB介绍 又一篇给Python程序员的

大白话讲解Promise(一)

去年6月份, ES2015正式发布(也就是ES6,ES6是它的乳名),其中Promise被列为正式规范.作为ES6中最重要的特性之一,我们有必要掌握并理解透彻.本文将由浅到深,讲解Promise的基本概念与使用方法. ES6 Promise 先拉出来遛遛 复杂的概念先不讲,我们先简单粗暴地把Promise用一下,有个直观感受.那么第一个问题来了,Promise是什么玩意呢?是一个类?对象?数组?函数? 别猜了,直接打印出来看看吧,console.dir(Promise),就这么简单粗暴. 这么一