析构函数的注意问题以及用new开出来的空间用free释放会怎样 | c++进阶学习一条龙(四)

大学学了越来越多的算法技术,但却不能忽略本源,编程语言是一切的基础,回过头来看依旧存在许多知识漏洞。返濮方能归真!!

前几天翻看别人的面经,发现了一个很有意思的问题,用new开出来的空间用free释放会怎样,借此机会,复习一下析构函数,并写了一个测试案例,来深度分析。

#include <iostream>
#include <string.h>
//#include <bits/stdc++.h> //c++万能头
using namespace std;

class test
{
private:
public:
    int num;
    char* str1;
    char* str2;
    test();
    ~test();
};

test::test()
{
    cout << "construct" << endl;
    num = 10;
    str1 =(char*)malloc(5);
    strcpy(str1, "abcd");
    str2=new char[5];
    strcpy(str2, "abcd");

}

test::~test()
{
    cout << "destroy" << endl;
    //free(str1);
    //delete []str2;
}


int main()
{
    test* a = new test();
    test* b = new test();
    cout << a->str2 << endl;
    cout << b->str2 << endl;
    cout << a->num << endl;
    cout << b->num << endl;
    delete a;
    delete b;
    cout << a->str2 << endl;
    cout << b->str2 << endl;
    cout << a->num << endl;
    cout << b->num << endl;
}

运行结果如下

可以发现两个对象在走完析构后,在栈区的变量num是完成了释放,而由我们自己开在堆区的字符串指针变量却没有释放,因此如果类中有自己动态开的空间,系统不会帮你释放,一定要在析构函数中自己释放。这样可以避免内存泄漏。

1、成员变量如果是指针。那么程序需要分配的内存是存储指针占用的内存(32位程序是4个字节)和指针指向的内存。其中指针占用的内存是有编译器管理的,而指针指向的内存是你自己管理的。也就是,这个指针占用的内存(4个字节)就会自动在析构函数里自动释放。但是指针指向的部分内存默认析构函数是不会帮你释放的,因为编译器也不知道你这个指针指向的是不是你自己分配的内存,也不知道你将来还会不会用这段内存。
2、当程序/进程执行完,程序占用的所有内存都会被操作系统释放。即使没有显示的delete

接下来对析构函数进行修改,将对象b改由用free释放。

#include <iostream>
#include <string.h>
//#include <bits/stdc++.h> //c++万能头
using namespace std;

class test
{
private:
public:
    int num;
    char* str1;
    test();
    ~test();
};

test::test()
{
    cout << "construct" << endl;
    num = 10;
    str1 =(char*)malloc(5);
    strcpy(str1, "abcd");

}

test::~test()
{
    cout << "destroy" << endl;
    free(str1);
    //delete[]str2;
}


int main()
{
    test* a = new test();
    test* b = new test();
    cout << a->str1 << endl;
    cout << b->str1 << endl;
    cout << a->num << endl;
    cout << b->num << endl;
    delete a;
    free(b);
    cout << a->str1 << endl;
    cout << b->str1 << endl;
    cout << a->num << endl;
    cout << b->num << endl;
    //system("cls");
    return 0;
}

运行结果

 可以看到对象b没有调用析构函数,num和字符串指针都没有被释放,也许有些编译器比较智能,能检查出问题,自动释放,有些情况,编译器不会报错,一些在栈区的变量例如num也许会被释放

但你动态开的绝不可能,因为根本没走析构函数。

一句话总结free去释放new开出来的对象不会走析构函数,对象里有些动态开的空间释放不了就会导致内存泄漏。

相反我们可以大胆的推测如果用malloc给对象开空间,再用delete释放,是不会走构造函数的,所有对象绝对不能用malloc开空间。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值