在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. bootstrap之google fonts

    bootstrap之google fonts 在学习一个bootstrap时,看到了一行引用代码:@import url(http://fonts.googleapis.com/css?family= ...

  2. MySQL表名和数据库关键字相同解决办法

    今天改他们的代码的时候,遇到了MySQL表名和数据库关键字的问题. 由于表名是关键字,导致增删改查都报错. Hibernate: select leave0_.id as id22_, leave0_ ...

  3. JavaScript 数组

    JavaScript 数组 简介:数组是值的有序集合,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. 一:创建数组 ...

  4. 步骤进度条 css

    用css写一个简单的步骤进度条 html代码: <h4>南京游玩</h4> <ul class="step-list"> <li> ...

  5. pythonchallenge 解谜 Level 4

    下一关... 一张图片,于是就点击了一下. 跳转到了 http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345 显示的是: ...

  6. 开源免费的HTML5游戏引擎

    青瓷引擎的成长 青瓷引擎自2015年4月项目启动开始,7月首次亮相2015年ChinaJoy,便得到业界的极大关注,随后开启限量测试,收到数百个开发者团队的试用申请及反馈,期间经历了18个内测版本,完 ...

  7. 为什么commonjs不适合于浏览器端

    有了服务器端模块以后,很自然地,大家就想要客户端模块.而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行. 但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境.还是上 ...

  8. AJAX学习随笔

    AJAX名为“啊,贾克斯”,听着挺怪的哈. 主要的技术就是XMLHttpRequest对象和Javascript 度娘的解答: AJAX即“AsynchronousJavascriptAndXML”( ...

  9. eclipse配置javah命令

    1.找到javah命令所在的目录    我的为 /usr/bin/javah 2.打开eclipse     如图点击第二项 3.配置  如图 ${project_loc}/src -classpat ...

  10. 解读ASP.NET 5 & MVC6系列(5):Configuration配置信息管理

    在前面的章节中,我们知道新版的MVC程序抛弃了原来的web.config文件机制,取而代替的是config.json,今天我们就来深入研究一下配置文件的相关内容. 基本用法 新版的配置信息机制在Mic ...