(2)释放
free();
void free(void *ptr);
malloc返回一个地址。 free接收一个地址。
内存分配特性:free接收的地址所释放的空间是固定的,在malloc申请完地址后,计算机所分配的字节数通常比所申请的空间大, 计算机会根据我们所需要的内存空间区间来分配一个合适的较大的空间。
注意事项:
1.有申请必须在使用完成后释放,否则可能造成内存泄漏:
2.malloc()必须对返回值判空,否则可能出现程序奔溃;
链表
链表包含表头和 结点(结构体)表头也称头结点,节点分为数据域和指针域。
位运算
注意事项:位运算符不能操作浮点型数据
~: 按位取反(单目运算符)
~a;
1111 1111 0101 1010
0000 0000 1010 0101
按位与运算符(&)
参加运算的两个数,按二进制位进行“与”运算。
运算规则:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
例:3 &5 即 00000011 & 00000101 = 00000001 ,所以 3 & 5的值为1。
按位或运算符(|)
参加运算的两个数,按二进制位进行“或”运算。
运算规则:参加运算的两个数只要两个数中的一个为1,结果就为1。
即 0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1 。
例:2 | 4 即 00000010 | 00000100 = 00000110 ,所以2 | 4的值为 6 。
异或运算符(^)
参加运算的两个数,按二进制位进行“异或”运算。
运算规则:参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。
例: 2 ^ 4 即 00000010 ^ 00000100 =00000110 ,所以 2 ^ 4 的值为6 。
<<:左移运算符(双目运算符)
a << n: 3 * 2 ^ n
0xfffeffff
1111 1111 1111 1110 1111 1111 1111 1111
0xfff7fff8
1111 1111 1111 0111 1111 1111 1111 1000
>>:右移运算符(双目运算符)
a >> n:3 / 2 ^ n
0xfffeffff
1111 1111 1111 1110 1111 1111 1111 1111
0x1fffdfff
0001 1111 1111 1111 1101 1111 1111 1111
操作对象为无符号数,高位 补零0
操作对象为有符号数,高位是0 补零0
1:算数右移 补零1
2. 逻辑右移 补零0
010101 01010 >>
123 / 10 => 12
123 /100 => 1
位运算符之—左移右移运算符(简单易懂)_左移运算符-优快云博客_左移运算符-优快云博客")
内存池
使用内存池的原因:
一直使用malloc和free非常容易产生内存碎片,早晚都会申请内存失败;并且在比较复杂的代码中,非常容易出现内存泄漏问题。
于是内存池应运而生,内存池预先分配一大块内存来做一个内存池,业务中的内存分配和释放都由这个内存池来管理,内存池内的内存不足时其内部会自己申请。所以内存碎片的问题就交由内存池的算法来优化,而内存泄漏的问题只需要遵守内存池提供的api,就非常容易避免内存泄漏了。