个人网站主机选择织梦网站版本

当前位置: 首页 > news >正文

个人网站主机选择,织梦网站版本,做网站不备案会怎样,对网站建设培训的建议目录 1、C/C内存区域划分 2、C动态内存管理#xff1a;malloc/calloc/realloc/free 3、C动态内存管理#xff1a;new/delete 3.1 new/delete内置类型 3.2 new/delete自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 5.1 内置类型 5.2 自定…目录 1、C/C内存区域划分 2、C动态内存管理malloc/calloc/realloc/free 3、C动态内存管理new/delete 3.1 new/delete内置类型 3.2 new/delete自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 5.1 内置类型 5.2 自定义类型 6、定位new表达式(placement-new) 了解 7、malloc/free和new/delete的区别 1、C/C内存区域划分 【说明】

  1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等栈是向下增长的。
  2. 内存映射段是高效的I/O映射方式用于装载一个共享的动态内存库。用户可使用系统接口 创建共享内存做进程间通信。Linux课程如果没学到这块现在只需要了解一下
  3. 堆用于程序运行时动态内存分配堆是可以向上增长的。
  4. 数据段(静态区)–存储全局数据和静态数据。
  5. 代码段(常量区)–可执行的代码/只读常量。 下面做一道题 int globalVar 1; static int staticGlobalVar 1; void Test() {     static int staticVar 1;     int localVar 1;     int num1[10] { 1, 2, 3, 4 };     char char2[] abcd;     const char* pChar3 abcd;     int* ptr1 (int*)malloc(sizeof(int) * 4);     int* ptr2 (int)calloc(4, sizeof(int));     int ptr3 (int*)realloc(ptr2, sizeof(int) * 4);     free(ptr1);     free(ptr3); }
  6. 选择题 选项 : A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区) globalVar在哪里____ staticGlobalVar在哪里____ staticVar在哪里____ localVar在哪里____ num1 在哪里____ char2在哪里____ * char2在哪里___ pChar3在哪里____ * pChar3在哪里____ ptr1在哪里____ * ptr1在哪里____ 答案 CCCAA AAADAB char2非静态局部变量在栈区   char2是一个数组把后面常量串拷贝过来到数组中数组在栈上所以*char2在栈上 pChar3非静态局部变量在栈区   pChar3得到的是字符串常量字符在代码段 2、C动态内存管理malloc/calloc/realloc/free malloccallocrealloc是向堆区申请空间的 void malloc (size_t size); malloc申请成功返回为类型为void的指针不会初始化申请失败返回NULL void calloc (size_t num, size_t size); calloc申请成功返回为类型为void*的指针空间的每个字节初始化为0申请失败返回NULL calloc malloc 初始化为0 (memset(void * ptr, 0, size_t num )) void* realloc (void* ptr, size_t size); 注意size 原来的空间大小 一段未使用的空间大小 realloc对动态开辟内存大小进行调整一般用于扩容 扩容存在两种情况 ◦ 情况1原有空间之后有足够大的空间 ◦ 情况2原有空间之后没有足够大的空间 情况1: 原有空间之后有足够大的空间 要扩展内存就在原有空间之后直接追加空间原来空间的数据不发生变化。 情况2: 原有空间之后没有足够大的空间 在堆空间上另找一个合适大小的连续空间来使用并把原来的数据 拷贝过去然后free原来的空间返回一个新的 内存地址。 realloc(NULL,size) malloc(size) void free (void* ptr); free是释放向堆区申请的空间 注意向堆区申请的空间只能释放一次一般释放完置为NULLNULL多次释放没有关系 3、C动态内存管理new/delete C动态内存管理方式在C中可以继续使用但有些地方就无能为力而且使用起来比较麻烦 因此C通过new和delete操作符进行动态内存管理。 3.1 new/delete内置类型 void Test() {// 动态申请一个int类型的空间int* ptr1 new int;// 动态申请一个int类型的空间并初始化为10int* ptr2 new int(10);// 动态申请10个int类型的空间int* ptr3 new int[10];// 动态申请10个int类型的空间并初始化为0int* ptr4 new int[10] {0};// 动态申请10个int类型的空间// 前5个初始化为1,2,3,4,5后5个初始化为0int* ptr5 new int[10]{1,2,3,4,5};delete ptr1;delete ptr2;delete[] ptr3;delete[] ptr4;delete[] ptr5; }int main() {Test();return 0; } 3.2 new/delete自定义类型 #include iostream using namespace std;class A { public:A(int a 0): _a(a){cout A(): this endl;}~A(){cout ~A(): this endl;}private:int _a 1; }; int main() {// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间//还会调用构造函数和析构函数A* p1 (A)malloc(sizeof(A));A p2 new A(1);free(p1);delete p2;// 内置类型是几乎是一样的int* p3 (int)malloc(sizeof(int)); // Cint p4 new int;free(p3);delete p4;A* p5 (A*)malloc(sizeof(A) * 10);A* p6 new A[10];free(p5);delete[] p6;return 0; } 注意 1、在申请自定义类型的空间时new会调用构造函数delete会调用析构函数而malloc与 free不会 2、申请和释放单个元素的空间使用new和delete操作符 申请和释放连续的空间使用 new[]和delete[]匹配使用不然坑的死死的 如了解一下A为8字节大小 前面开4个字节大小的空间是为了存放需要调用析构函数的次数 对于没有必要调用的析构函数编译器可能会进行优化不开这个空间A的析构函数必须被调用因为有打印字符串 delete p3是释放80字节大小的空间因为不能从中间位置释放空间所以报错内存泄漏不报错 4、operator new与operator delete函数 operator new 和 operator delete是 系统提供的全局函数 注意operator new 实际也是通过malloc来申请空间如果 malloc申请空间成功就直接返回否则执行用户提供的空间不足应对措施如果用户提供该措施 就继续申请否则就抛异常。operator delete 最终是通过free来释放空间的。 /*operator new该函数通过malloc来申请空间当malloc申请空间成功时直接返回申请空间 失败尝试执行空间不足应对措施如果该应对措施用户设置了则继续申请否则抛异常。 / void CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) {// try to allocate size bytesvoid* p;while ((p malloc(size)) 0)if (_callnewh(size) 0){// report no memory// 如果申请内存失败了这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}return (p); }/* operator delete: 该函数最终是通过free来释放空间的 / void operator delete(void pUserData) {_CrtMemBlockHeader* pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData NULL)return;_mlock(_HEAP_LOCK); /* block other threads */TRY/* get a pointer to memory block header /pHead pHdr(pUserData);/ verify block type /_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-nBlockUse));_free_dbg(pUserData, pHead-nBlockUse);__FINALLY_munlock(_HEAP_LOCK); / release other threads */__END_TRY_FINALLYreturn; }/*free的实现 /#define free(p) _free_dbg(p, _NORMAL_BLOCK) 5、new和delete的实现原理 5.1 内置类型 new和mallocdelete和free基本类似 不同 new/delete申请和释放的是单个元素的空间new[]/delete[]申请的是连续空间而且new在申请空间失败时会抛异常malloc会返回NULL。 5.2 自定义类型 new的原理 1. 调用operator new函数申请空间 2. 在申请的空间上调用构造函数完成对象的初始化 delete的原理 1. 在释放的对象空间上调用析构函数完成对象中资源的清理工作 2. 调用operator delete函数释放对象的空间 new T[N]的原理 1. 调用operator new[]函数在operator new[]中实际调用operator new函数完成N个对象空间的申请 2. 在申请的空间上调用N次构造函数完成对N个对象的初始化 delete[N]的原理 1. 在释放的对象空间上调用N次析构函数完成N个对象中资源的清理工作 2. 调用operator delete[]释放空间在operator delete[]中实际调用operator delete来释放空间 6、定位new表达式(placement-new) 了解 定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。 使用格式 new (place_address) type或者new (place_address) type(initializer-list)
    place_address必须是一个指针initializer-list是类型的初始化列表 使用场景 定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化所以如果是自定义类型的对象需要使用new的定位表达式进行显示调用构造函数进行初始化。 #include iostream using namespace std;class A { public:A(int a 0): _a(a){cout A(): this endl;}~A(){cout ~A(): this endl;} private:int _a; };// 定位new/replacement new int main() {// p1现在指向的只不过是与A对象相同大小的一段空间还不能算是一个对象因为没有调用构造函数A
    p1 (A)malloc(sizeof(A));new(p1)A; // 注意如果A类的构造函数有参数时此处需要传参p1-~A(); // 析构可以直接显示调用显示调用构造函数要通过定位new表达式free(p1);A p2 (A*)operator new(sizeof(A));new(p2)A(10);p2-~A();operator delete(p2);return 0; } 7、malloc/free和new/delete的区别 malloc/free和new/delete的共同点是都是从堆上申请空间并且需要用户手动释放。 不同
  7. malloc/free是函数new/delete是操作符
  8. malloc申请的空间不会初始化new会初始化
  9. malloc申请空间时需要手动计算空间大小  new只需在其后跟上空间的类型即可 如果是多个对象[]中指定对象个数即可
  10. malloc的返回值为void*, 在使用时必须强转new不需要因为new后跟的是空间的类型
  11. malloc申请空间失败时返回的是NULL因此使用时必须判空new需要捕获异常
  12. 申请自定义类型对象的空间时malloc/free只会开辟空间不会调用构造函数与析构函数 而new 在申请空间后会调用构造函数完成对象的初始化delete在释放空间前会调用析构函数完成 空间中资源的清理释放