Chapter2.h
#ifndef __CHAPTER_2_ #define __CHAPTER_2_ /*《深入理解C指针》学习笔记 -- 第二章*/ /* 内存泄露的两种形式 1.忘记回收内存 2.内存地址丢失 */ void __memory_leak_test(); /* 内存操作的几个函数 malloc alloc realloc free */ void __memory_function_test(); #endif
Chapter2.cpp
#include "Chapter2.h" #include <stdio.h> #include <malloc.h> #include <assert.h> /* 内存泄露的两种形式 1.忘记回收内存 2.内存地址丢失 */ void __memory_leak_test() { /*申请了内存可是忘记了回收不用的内存*/ int* p_test1 = (int*)malloc(sizeof(int)); *p_test1 = 1; // do_something_to : p_test1 /*当不须要再使用 p_test1 时,应该及时释放内存,并赋值 NULL*/ /* free(p_test1); p_test1 = NULL; */ /*内存地址在程序中丢失了,导致没有办法释放掉申请(堆中)的内存*/ int* p_test2 = (int*)malloc(sizeof(int)); *p_test2 = 2; // do_something_to : p_test2 /*当不须要再使用 p_test2 时,应该及时释放内存。并赋值 NULL*/ /* free(p_test2); p_test2 = NULL; */ /*可是这个时候。又又一次申请了别的内存。导致,原来的内存地址丢失了*/ p_test2 = (int*)malloc(sizeof(int)); /*不须要使用这块内存后。应该显示的释放内存*/ free(p_test2); p_test2 = NULL; } void __memory_function_test() { /* malloc 函数用于分配内存,返回 void* 类型的指针。指向分配内存的初始地址。 可是不正确这块内存进行初始化的操作 当内存申请失败时,返回NULL */ int* p_test1 = (int*)malloc(sizeof(int)); /* 假设申请的内存比較大,那么须要推断是是否申请失败,一般申请小的内存块不须要这种操作 */ assert(p_test1 != NULL); //do_something_to_p_test1 /*使用完内存后应该及时释放,避免内存泄露*/ free(p_test1); /* calloc 函数,从堆上分配内存,与 malloc 函数的不同之处在于 它会对申请的内存进行清零的操作 当内存申请失败时,返回NULL */ int* p_test2 = (int*)calloc(2, sizeof(int)); /* 上面的操作能够利用 malloc 和 memset 实现 int *p_test2 = (int*)malloc(2 * sizeof(int)); memset(p_test2, 0, 2 * sizeof(int)); */ /* 假设申请的内存比較大,那么须要推断是是否申请失败。一般申请小的内存块不须要这种操作 */ assert(p_test2 != NULL); //do_something_to_p_test2 /*使用完内存后应该及时释放。避免内存泄露*/ free(p_test2); /* realloc 函数。一般用于对原来申请的内存做处理,申请更大的内存。或者缩小内存 1.假设參数为0。那么代表释放内存,就好像是使用 free 一样 2.假设申请的内存比当前分配的内存小,那么多余的内存会还给堆 3.假设申请的内存比当前分配的内存大,假设可能会紧挨着当前的内存的区域分配新的更大的内存。 否则。就在堆的其它区域分配并把旧的内存拷贝到新的区域 */ char* p_test3; char* p_test4; char* p_test5; p_test3 = (char*)malloc(8 * sizeof(char*)); printf("p_test3 address is : %x ", p_test3); p_test4 = (char*)realloc(p_test3, 64 * sizeof(char*)); printf("p_test4 address is : %x ", p_test4); p_test5 = (char*)realloc(p_test4, 65 * sizeof(char*)); printf("p_test5 address is : %x ", p_test5); /* 上述样例的执行结果例如以下: p_test3 address is : 53a848 p_test4 address is : 53a8e0 又一次找了一个新的区域分配更大的内存 p_test5 address is : 53a8e0 在原来的内存上面分配更大的内存 */ /* 不要反复释放内存,否则结果是没有定义的,例外是释放空指针(NULL) */ int* p_test6 = (int*)malloc(sizeof(int)); /* free(p_test6); 这里是正确的操作 free(p_test6); 这里就会出现故障,由于释放了已经释放的内存 */ /* free(p_test6); 这里是正确的操作 p_test6 = NULL; free(p_test6); 这里尽管是多次释放,可是前一步操作已经给指针赋值 NULL,free 不会出现故障 */ }