企业年报系统官网,无锡seo网站推广费用,为什么网站要改版,设计网站官网有哪些相关文章
C智能指针 文章目录 相关文章前言一、new 运算符1. operator new 函数的范围2. 在类中重载new运算符3. 分配失败 二、delete 运算符1. 内存泄露统计示例2. 在类中重载delete运算符 总结 前言 在C中#xff0c;new和delete是用于动态内存管理的运算符#xff0c;它们…相关文章
C智能指针 文章目录 相关文章前言一、new 运算符1. operator new 函数的范围2. 在类中重载new运算符3. 分配失败 二、delete 运算符1. 内存泄露统计示例2. 在类中重载delete运算符 总结 前言 在C中new和delete是用于动态内存管理的运算符它们允许程序在运行时动态地分配和释放内存而不需要在编译时知道确切的内存需求。动态内存分配是指在程序运行时根据需要分配内存空间而静态内存分配是指在编译时分配内存空间。new和delete是C中实现动态内存分配和释放的关键工具。 new运算符用于在堆上动态分配内存。它可以用于分配单个对象或数组。当使用new来分配单个对象时它会返回一个指向所分配内存空间的指针并自动调用对象的构造函数来初始化对象。当使用new来分配数组时它会分配足够的内存来存储整个数组并返回指向数组第一个元素的指针。这样程序可以根据需要动态地创建数组而不需要在编译时知道数组的大小。 delete运算符用于释放由new分配的内存。对于单个对象使用delete对于数组使用delete[]。当不再需要动态分配的内存时应该使用delete来释放内存以防止内存泄漏。delete会调用对象的析构函数来清理对象并释放所分配的内存。这样程序可以在不需要内存时及时释放它以避免内存资源的浪费。 new和delete提供了灵活的内存管理机制使程序能够根据需要动态地分配和释放内存。然而它们需要谨慎使用因为错误的使用可能导致内存泄漏、悬空指针等问题。例如在使用new分配内存后如果忘记使用delete释放内存就会导致内存泄漏而在使用delete释放内存后如果继续使用指向已释放内存的指针就会导致悬空指针问题。因此在使用new和delete时需要确保正确地匹配内存的分配和释放并避免出现悬空指针的情况。 C 支持使用 new 和 delete 运算符动态分配和解除分配对象。 这些运算符为来自称为“自由存储”也称为“堆”的池中的对象分配内存。 new 运算符调用特殊函数 operator newdelete 运算符调用特殊函数 operator delete。
一、new 运算符
operator new的第一个参数必须为 size_t 类型且返回类型始终为 void*编译器将如下语句转换为对函数 operator new 的调用
char *p new char[64];重复调用 operator new 会返回不同的地址指针。
如果要申请的的存储空间为零字节operator new 将返回指向不同对象的指针
#include iostream
using namespace std;int main()
{char *p1 new char[0];char *p2 new char[0];char *p3 new char[0];cout p10x (int*)p1 endl;cout p20x (int*)p2 endl;cout p30x (int*)p3 endl;return 0;
}如果分配请求的内存不足operator new 会引发 std::bad_alloc 异常。 或者如果使用了 placement 形式 new(std::nothrow)或者链接在非引发的 operator new 支持中它将返回 nullptr。
1. operator new 函数的范围
运算符范围::operator new全局class-name::operator new类
在使用 new 运算符分配内置类型的对象、不包含用户定义的 operator new 函数的类类型的对象和任何类型的数组时将调用全局 operator new 函数。 在使用 new 运算符分配类类型的对象时其中定义了 operator new将调用该类的 operator new。
2. 在类中重载new运算符
示例
#include memory.h
#include iostream
using namespace std;class Test
{
public:Test() {cout Test() endl;}void *operator new(size_t size){//可以自定义空间申请规则cout operator new endl;return malloc(size);}
};int main()
{Test *p new Test;return 0;
}执行结果
执行流程
在类声明中支持数组的 new 运算符。 例如
#include memory.h
#include iostream
using namespace std;class Test
{
public:Test() {cout Test() endl;}void *operator new[](size_t size){cout operator new[] endl;return malloc(size);}
};int main()
{Test *p new Test[5];return 0;
}执行结果
3. 分配失败
C 标准库中的 new 函数支持自 C98 以来在 C 标准中指定的行为。 如果分配请求的内存不足operator new 会引发 std::bad_alloc 异常。标准 C 要求分配器引发 std::bad_alloc 或派生自 std::bad_alloc 的类。 可以处理此类异常如以下示例所示
#include iostream
using namespace std;int main()
{size_t n 20000000000L;try {int *p new int[n];cout p endl;}catch (bad_alloc ex) {cout 申请内存失败: ex.what() endl;}return 0;
}执行结果 二、delete 运算符 可使用 delete 运算符释放使用 new 运算符动态分配的内存。 delete 运算符调用 operator delete 函数该函数将内存释放回可用池。 使用 delete 运算符也会导致调用类析构函数如果存在。
1. 内存泄露统计示例 能过自定义 operator new 和 operator delete 函数来记录申请内存和释放的次数判断是否存在内存泄露示例如下
#include iostream
using namespace std;bool bLog 0;
int nAllocated 0;void *operator new(size_t size) { nAllocated;cout 申请内存 nAllocated 大小 size \n;return malloc(size);
}void operator delete(void *p) {--nAllocated;clog 释放内存 nAllocated \n;free(p);
}int main() {for (int i 0; i 10; i) {char *p new char[10];delete[] p;}cout nAllocated endl;return 0;
}2. 在类中重载delete运算符
示例如下
#include iostream
using namespace std;class Test {
public:Test() {cout Test() endl;}~Test() {cout ~Test() endl;}void *operator new(size_t size){cout operator new endl;return malloc(size);}void *operator new[](size_t size){cout operator new[] endl;return malloc(size);}void operator delete (void* p) {cout operator delete(void*) endl;free(p);}void operator delete[](void* p) {cout operator delete[](void*) endl;free(p);}};int main() {Test *p1 new Test;delete p1;cout ------------------\n;Test *p2 new Test[5];delete[] p2;return 0;
}执行结果: 执行过程 总结 new和delete是C中用于动态内存管理的运算符它们提供了灵活的内存分配和释放机制但需要谨慎使用以避免内存泄漏和悬空指针等问题。随着智能指针的引入程序员可以更安全地进行动态内存管理减少了对new和delete的直接使用提高了程序的可靠性和可维护性。 ✍结尾 ❤️ 感谢您的支持和鼓励关注不迷路✍