应用层对new,free混合搭配的分析
补充说明
malloc一个指针delete / delete[] 掉 : POD类型没事,有非travel析构函数的会出事
free
free(NULL)合法
free(野指针)大概率崩溃,小概率没事,具体要分析源代码
连续两次free,在一些非常有限的情况下,不会崩溃
多次free,在大多数情况下会导致崩溃
手动调用构造和析构函数
比较诡异,c++可以显示调用析构函数,比如A a;a.~A(),但是不能显式调用构造函数
并且,编译器会在对象生命周期结束时,自动调用构造函数
利用定位new表达式可以显示调用构造函数,定位new就这一个用途
operator new
operator new是可以重载的函数
首先new operator 和 operator new不一样,不清楚的百度一下
operator new是一个可以用户重载的函数,负责开辟空间(不负责初始化、调用构造函数)
全局operator new一般默认调用malloca开辟空间,全局operator new不应该被重载
但是,可以在类里面重载operator new
编译器在new class()的时候会自动调用重载的operator new,分配空间
特别是,在基类里面重载operator new,会应用到所有派生类
这是一种特别优雅的做法,应用于大规模库比如MFC
operator new重载有一些规定,自己百度
new operator
new operator是运算符
c++标准保证了new operator的行为 :先分配内存,然后初始化
new的时候,本质上先调用operator new分配内存,然后再调用构造函数
new type[]
对于有构造函数的类型,new []申请 4字节 + size大小的内存,4字节用来存储数组长度
为什么要存储数组长度?构造/析构的时候要用
对于没有构造函数的类型,编译器不浪费空间记录数组长度
auto p = new 没有构造函数的POD类型[100];free(p);也没事
所以
auto p = new char[100]();
free(p);
// 没问题 
auto p = new string[100]();
free(p);
// 有问题
面试问题,当free,new这些混用起来时,会出现什么情况?
捋到这里,这些问题就很清晰了
无非两个问题
1.对象有没有正确构造、析构
2.free,delete,delete []的时候,会不会导致free()崩溃
如何限制对象仅仅在堆上生长
采用 CRTP,很方便
private 析构函数也行,缺点是不能正常delete
CRTP真好用
#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
template<typename T>
struct base
  {
  	template<typename ...Args>
  	static T* create(Args &&... args)
  	  {
  	  	return new T(std::forward<Args>(args)...);
		}
  };
struct son : base<son>
  {	
    friend class base<son>;
  	ll val;
  	protected :
	  	son(ll val)
	  	  : val(val)
	  	    {}
	  	son(son const& rhs)
	  	  {}
  };
int main()
  {
  	auto p = son::create(10);
  	cout << p -> val << endl;
	delete p;
	return 0;
  }
如何限制对象仅仅在栈上生长
思路就是找operator new下手,注意重载格式
#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
struct base
  {
    void* operator new(size_t) = delete;      // 注意函数的第一个参数和返回值都是固定的  
    void  operator delete(void*) = delete;    // 重载了new就需要重载delete  
  };
struct son : base
  {	
  	ll val;
  	son(ll val)
  	  : val(val)
  	    {}
  	son(son const& rhs)
  	  {}
  };
int main()
  {
  	son a(10);
  	cout << a.val << endl;
  	//auto  p = new son(10);
	return 0;
  }
本文来自博客园,作者:XDU18清欢,转载请注明原文链接:https://www.cnblogs.com/XDU-mzb/p/14852289.html
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号