在C++中也是少不了对内存的管理,在C++中只要有new的地方,在写代码的时候都要想着delete。 new分配的时堆内存,在函数结束的时候不会自动释放,如果不delete我分配的堆内存,则会造成内存泄露。所以我们要学会内存管理,不要内存泄露。在C++中的内存管理机制和OC中的还不太一样,在OC中的ARC机制会给程序员的内存管理省不少事,但在C++中没有ARC所以我们要自己管理好自己开辟的内存。Java中也有自己相应的内存管理机制,比如JDBC里的获取的各种资源在finally里进行close等

那么什么情况下我们写的程序会出现内存泄露呢?下面我们将会举一个简单的例子来分析一下C++中的内存管理机制。

1.建立一个测试类TestClass, TestClass类中有一个私有的属性(指针类型),有一个无惨的构造函数,有一个析构函数,还有一个display方法用于输出对象的信息

测试类的声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//内存管理的测试类
class TestClass
{
private:
    char *name;
public:
    //无参构造函数
    TestClass();
    //析构函数
    ~TestClass();
    //描述方法
    void display();
};

   在xxx.cpp文件中定义类的实现方法

实现构造方法,实现构造方法时要给属性指针分配空间,不然的话属性指针没有分配内存地址,调用时程序会崩溃,用new方法进行堆分配

1
2
3
4
5
6
7
8
9
//无参构造函数
TestClass::TestClass()
{
    cout << "TestClass()" <<endl;
    //给指针属性分配内存(堆分配)
    this->name = new char[255];
    //进行初始化
    strcpy(this->name, "ludashi");
}

实现析构函数在析构函数中要对构造函数中堆分配的内存进行delete,不然会造成内存泄露

1
2
3
4
5
6
//析构函数
TestClass::~TestClass()
{
    delete [] this->name;
    cout << "~TestClass()" << endl;
}

实现display函数,进行name的打印测试

1
2
3
4
5
//描述方法
void TestClass::display()
{
    cout << this->name <<endl;
}

2. 在main函数中进行测试

实例化对象时进行堆分配:需要手动进行内存的释放,不然也会造成内存的泄露

1
2
//TestClass类的初始化,堆分配,需要delete
TestClass * testClass = new TestClass();

实例化对象的栈分配:不需要手动释放内存,大括号结束时就自动释放栈内存

1
2
//栈分配,不用delete,出大括号后自动释放
 TestClass stackClass = TestClass()

信息的打印输出

1
testClass->display();

调用delete来释放堆分配的对象

1
delete testClass;

3.程序运行结果:如果不加delete testClass; 析构函数只会调用一个,因为堆分配的对象不会自动释放,需要手动释放,不加则会造成内存的泄露

1
2
3
4
5
TestClass()
TestClass()
ludashi
~TestClass()
~TestClass()

4.拷贝构造函数

如果在main函数中加入下面这句话,程序在运行时就会崩掉,如果要想程序正常运行可以把析构函数中的delete [] this->name;注释掉就可以运行。不过这样会引起内存的泄露。那么我们来研究一下为什么加上下面这句话程序会崩掉呢?原因是下那句话的意思是copyTest和stackClass指向同一块栈内存,当其中一个调用析构函数时就会把name给delete掉,另一个在析构调用delete时就会报错。怎么从基本上解决问题呢?接下来就是拷贝构造函数出场的时候啦。

1
TestClass copyTest = stackClass;

下面是拷贝构造函数的定义方法

1
2
3
4
5
6
7
8
//拷贝构造函数
TestClass::TestClass(const TestClass &test)
{
    //在堆中分配新的内存
    this->name = new char[255];
    //进行拷贝
    strcpy(this->name, test.name);
}

在main函数中调用拷贝构造函数 ,这样的代码有不会有刚才的问题了

1
TestClass copyTest = stackClass;

5.再提内存管理,不禁又想到初学C++那会的一句话“先构造的后析构”;有new的地方就得想着delete,为了避免内存泄露。

​    ​上面的拷贝构造函数的作用是在声明对象的时候可以利用拷贝构造函数给新的对象赋值,如果像下面的这种情况就会出现过度释放的问题;  ​

1
2
3
TestClass  test1 = TestClass();
TestClass  test2 = TestClass();
test2 = test1;

​    ​接下来就该操作符重载出场的时候了(operator = )把=号进行重载

1
2
3
4
5
6
//对象之间的赋值:操作符重载
TestClass & TestClass :: operator = (const TestClass &test)
{
    strcpy(this->name, test.name);
    return *this;
}

C++中的内存管理的更多相关文章

  1. Unity游戏开发中的内存管理_资料

    内存是手游的硬伤——Unity游戏Mono内存管理及泄漏http://wetest.qq.com/lab/view/135.html 深入浅出再谈Unity内存泄漏http://wetest.qq.c ...

  2. cocos2dx中的内存管理机制及引用计数

    1.内存管理的两大策略: 谁申请,谁释放原则(类似于,谁污染了内存,最后由谁来清理内存)--------->适用于过程性函数 引用计数原则(创建时,引用数为1,每引用一次,计数加1,调用结束时, ...

  3. Cocos2d-x开发中C++内存管理

    由于开始并没有介绍C++语言,C++的内存管理当然也没进行任何的说明,为了掌握Cocos2d-x中的内存管理机制,是有必要先了解一些C++内存管理的知识.C++内存管理非常复杂,如果完全地系统地介绍可 ...

  4. 6.关于QT中的内存管理,动态的制作,动态库的调用,静态库的制作

     一  QT的内存管理 1  QT中的内存管理是QObject来管理的 2  QT中的内存管理没有cocos2dx中的引用计数 3  组件能够指定父对象 QTimer *timer = QTime ...

  5. C语言中的内存管理

    开始陆续的发一下唐老师视频的笔记吧,顺便带一些正冲哥书的的内容.不能一下都发出来,因为内容发多了自己也受不了,而且发的都是学习视频时候的一些笔记,可能会有一些问题不是很清晰. 先说一下C语言中的内存管 ...

  6. JNI中的内存管理(转)

    源:JNI中的内存管理 JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互 ...

  7. javascript中的内存管理和垃圾回收

    前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...

  8. php中的内存管理的介绍(转)

    本篇文章给大家带来的内容是关于php中的内存管理的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.php内存管理概述——Zend引擎 由于计算机的内存由操作系统进行管理,所以 ...

  9. Android中的内存管理机制以及正确的使用方式

    概述 从操作系统的角度来说,内存就是一块数据存储区域,属于可被操作系统调度的资源.现代多任务(进程)的操作系统中,内存管理尤为重要,操作系统需要为每一个进程合理的分配内存资源,所以可以从两方面来理解操 ...

随机推荐

  1. JavaWeb中读取文件资源的路径问题

    在做javaweb开发的时候,我们可能会需要从本地硬盘上读取某一个文件资源,或者修改某一个文件,这个时候就需要先找到这个文件,然后用FileInputStrem等文件字节.字符流来将这个文件读取到内存 ...

  2. vue.js的基本操作

    1.{{message}}输出data数据中的message. 2.v-for="todo in todos"输出data数据中的dotos数组 3.v-on:click=&quo ...

  3. html websocket

    from:http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/ websocket 规范升级过,在该链接的文章内未提及,后面 ...

  4. TestNG 与 Junit的比较

    转自 http://www.blogjava.net/fanscial/archive/2005/12/14/23780.html 1.         JDK 5 Annotations (JDK ...

  5. tomcat报错java.lang.IllegalArgumentException: Document base XXXXX does not exist or is not a readable directory

    启动tomcat的时候报如下错误: java.lang.IllegalArgumentException: Document base F:\java\tools\tomcat\me-webapps\ ...

  6. Java基础系列——IO流

    ---恢复内容开始--- Java对数据的操作都是通过流的方式,数据的输入和输出是相对内存来说的,将外设的数据读到内存:输入流:将内存的数据写到外设:输出流. 流按操作数据分为两种:字节流,字符流. ...

  7. Building Modern Web Apps-构建现代的 Web 应用程序(一些感想)

    <iframe src="http://channel9.msdn.com/Series/MVA-China/Web20140611A01/player?h=540&w=960 ...

  8. ASP.Net WebForm温故知新学习笔记:二、ViewState与UpdatePanel探秘

    开篇:经历了上一篇<aspx与服务器控件探秘>后,我们了解了aspx和服务器控件背后的故事.这篇我们开始走进WebForm状态保持的一大法宝—ViewState,对其刨根究底一下.然后,再 ...

  9. C++高精度计时器——微秒级时间统计

    在C++中,经常需要通过计时来统计性能信息,通过统计的耗时信息,来分析性能瓶颈,通常情况下,可能毫秒级别的时间统计就足够用了,但是在毫厘必争的性能热点的地方,毫秒级别的统计还是不够的,这种情况下,就需 ...

  10. upload4j安全、高效、易用的java http文件上传框架

    简介 upload4j是一款轻量级http文件上传框架,使用简单,实现高效,功能专一,摆脱传统http文件上传框架的繁琐. upload4j的诞生并不是为了解决所有上传需求,而是专注于基础通用需求. ...