您的位置:首页 > 汽车 > 时评 > 湛江网站建设优化推广_b站推广网站mmm名星_百度关键词怎么优化_经典品牌推广文案

湛江网站建设优化推广_b站推广网站mmm名星_百度关键词怎么优化_经典品牌推广文案

2025/3/18 21:00:55 来源:https://blog.csdn.net/2201_75570391/article/details/146258335  浏览:    关键词:湛江网站建设优化推广_b站推广网站mmm名星_百度关键词怎么优化_经典品牌推广文案
湛江网站建设优化推广_b站推广网站mmm名星_百度关键词怎么优化_经典品牌推广文案

这里写目录标题

  • 1.new
    • 1.1new的使用
    • 1.2new自定义类型对比malloc
  • 2.delete
  • 2.1delete的使用
  • 2.2delete自定义类型对比free
  • 3.全局函数operator new
  • 4.全局函数operator delete
  • 5.new和delete的实现原理

在C语言中,有四个内存管理函数:malloc,calloc,realloc和free
但是它们的使用十分的不方便
例:
int* p = (int*)malloc(sizeof(int) * n);
malloc函数不会初始化变量,如果变量是自定义类型,C语言的内存管理函数无法自动调用变量的构造和析构函数

1.new

申请单个元素的空间,使用new操作符,申请连续的空间,使用new[]

1.1new的使用

  1. 开辟多个空间
int* p = new int[100];

开辟100个int类型的空间,将空间的地址赋值给p指针变量

  1. 开辟一个空间并初始化
int main()
{int* p = new int(10);return 0;
}

申请一个int类型的空间并初始化值为10

  1. 申请连续的空间并初始化
int main()
{int* p = new int[10] {1, 2, 3, 4};//申请10个int的空间并初始化return 0;
}

申请10个int类型的空间并初始化了前四个空间的值,替他空间

1.2new自定义类型对比malloc

new自定义类型用法与内置类型相同

  1. 在申请自定义类型的空间时,new会调用构造函数,malloc不会
  2. new可以初始化变量的内容
class A
{
public:A(int a = 0): _a(a){cout << "A():" << this << endl;}~A(){cout << "~A():" << this << endl;}
private:int _a;
};int main()
{A* p = (A*)malloc(sizeof(A) * 10);free(p);A* p1 = new A[2];delete[]p1;return 0;
}

2.delete

2.1delete的使用

  1. 直接使用delete
int* p = new int(10);
//使用指针p
delete p;
  1. 使用delete[]
int* p = new int[10]{1,2,3,4};
//使用指针p
delete[] p;

当new使用方括号[]开辟多个空间时,delete也要对应的加上[]来释放空间,否则会报错

2.2delete自定义类型对比free

  1. delete会调用自定义类型的析构函数,而free不会
  2. delete面对不同的情况需要加上[ ],然而free不用考虑
class stack
{
public:stack()//构造{cout << "stack()" << endl;_a = new int[4];_top = 0;_capacity = 4;}~stack()//析构{cout << "~stack()" << endl;delete[] _a;    _top = _capacity = 0;}
private:int* _a;int _top;int _capacity;
};int main()
{stack p;stack*p1 = new stack;delete p1;return 0;
}

类的实例化对象生成p,在栈上,调用构造函数,在堆上开辟了4个int类型的数组
p1是一个指针,在栈上指向在堆上申请的一个stack, 再调用构造函数,_a=newstack[4],_a再次指向在堆上申请的4个int类型的数组
若将delete p1改为 free(p1),会少调用析构函数,直接释放stack空间
导致无法释放堆上申请的4个int类型的数组,从而导致内存泄露

3.全局函数operator new

operator new是全局函数,不是运算符重载

库中的operator new函数:

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
void *p;
while ((p = malloc(size)) == 0)if (_callnewh(size) == 0){// 如果申请内存失败了,这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}
return (p);
}

new的底层实际上是使用了malloc来实现开辟空间
开辟空间成功,会返回指向此空间的指针
开辟空间失败,会抛异常

4.全局函数operator delete

库中的operator delete函数:

#define free(p) _free_dbg(p, _NORMAL_BLOCK)
void operator delete(void *pUserData)
{_CrtMemBlockHeader * pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData == NULL)return;_mlock(_HEAP_LOCK);__TRYpHead = pHdr(pUserData);_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));_free_dbg( pUserData, pHead->nBlockUse );__FINALLY_munlock(_HEAP_LOCK);__END_TRY_FINALLYreturn;
}

delete里面调用了:_free_dbg(p, _NORMAL_BLOCK),此函数正是free函数定义的宏替换,说明delete的底层实现实际上是调用了C语言中的free函数,delete是使用free来释放空间的

5.new和delete的实现原理

new的原理步骤:

  1. 调用operator new函数申请空间
  2. 在申请的空间上执行构造函数完成对象的构造

new T[N]的原理步骤:

  1. 调用operator new[]函数完成N个对象空间的申请
  2. 在申请的空间上执行N次构造函数

delete的原理步骤:

  1. 在空间上执行析构函数完成对象中资源的清理工作
  2. 调用operator delete函数释放对象的空间

delete[]的原理步骤:

  1. 在释放的对象空间上执行N次析构函数完成N个对象中资源的清理
  2. 调用operator delete[]释放空间

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com