C语言-动态分配内存 malloc & free
需要用一个数组来保存用户的输入,但是却不知道用户会输入多少条数据。
(1) 如果设一个太大的数组,则显得浪费内存
(2) 如果设得太小,又怕不够
问题:如何做到恰好够用、又一点不浪费呢?
系统中存在一个内存管理器(MM, Memory Manager),它负责管理一堆闲置内存。它被设计用于解决此类问题。
MM提供的服务:应用程序可以向MM申请(借出)一块指定大小的内存,用完之后再释放(还回)。
应用程序在使用malloc时,要把返回值转换成目标类型。
这块内存和数组没有本质区别,用法完全相同。
需要先计算需要多少字节的内存空间
数组举例子:
释放的时候需要注意, 因为在for循环执行之后,p的地址往前移动了10, 所以需要减去10, 然后再释放p,不然会有问题
// 当销毁时只需要free一次,malloc了几个字节就会free几个字节,和char类型还是int类型无关
free(p);
在一个函数中动态分配的内存,在另一个函数中操作这块内存
(1) MM是一个系统级的东西,所有的应用程序都向同一个MM申请内存。
(2) 何为借出?实际上,在内存被借出时,MM只是把它管理的内存标记了一下,表示该段内存已经被占用。比如,它把每一段被占用的内存给记录下来(首地址,长度)
(p0,n0) (p1, n1) (p2, n2) ...
(3) MM非常慷慨:①只要有人 malloc ,它都同意借出 ②你不归还,它永远不会主动要求你 free 。
(4) MM管理的内存区域称为“堆”Heap
这意味着,用户程序应该自觉得及时 free ,以便不耽误别的应用程序的使用。如果有个应用程序不停地 malloc ,而不 free ,那最终会用光MM的内存。当MM没有更多闲置内存时, malloc 返回 NULL ,表示内存已经用完。
再次重申: 应用程序在malloc之后,应该尽早free !
使用原则:需要的时候再申请,不需要的时候立即释放
实际上,MM对借出的内存块进行标识
(p0, n0) (p1, n1) (p2, n2) ...
它内部已经保证任意两块内存不会“交叠”,即不会重叠,不会把一块内存同时借给两个应用程序使用。
所以,每块内存的首地址都是不同的,在 free 的时候只需要指明首地址即可。
对象指的一块内存
示例:用Citizen表示一个市民,用Car表示一个辆车。他起初没有车,但未来可能有一辆车。
怎么样才算“及时”? “不及时”会怎样?
MM里可用的内存是有限的,你用完了就得尽快还,因为别的应用程序也需要MM的内存。
只借不还,积累到一定程度,MM没有更多内存可用,于是malloc返回NULL。
要还就得全还,否则MM那边处理不了
原因是:MM可能此时没有闲置内存可用。(虽然这种情况一般不会发生)
free之后,该内存交还给MM,该内存不再可用(失效)
不一定要在相同的函数里释放,在应用程序的任意一个角落释放都是有效的。
也就是说:这一块内存被malloc出来之后,完全交给你处置
功能:将 s 中当前位置后面的 n 个字节 (typedef unsigned int size_t )用 ch 替换并返回 s
参数:
参数:
功能:由 src 所指内存区域复制 n 个字节到 dest 所指内存区域。
memmove() 功能用法和 memcpy()) 一样,区别在于: dest
和 src 所指的内存空间重叠时, memmove() 仍然能处理,不过执行效率比 memcpy() 低一些