Skip to content

Dynamic memory

C Programming Lesson 16 2:26 English narration · English + 中文 subtitles burned in

space play · ←/→ 5s · j/l 10s · f fullscreen · ,/. speed

Chapters

Transcript
Every local variable you have written so far lives on the stack. 你目前写过的每一个局部变量都住在栈上。
It appears when the function starts and vanishes when it returns, which is usually exactly what you want. 它在函数开始时出现,在函数返回时消失, 通常这正是你想要的。
But sometimes you need memory that survives the function, or a size you only learn while the program is running. 但有时候你需要能活过这个函数的内存, 或者一个只有在程序运行时才知道的大小。
For that you ask the heap. 那就得向堆申请。
And this explains a classic C bug: return a pointer to a local array and the caller gets an address whose contents are already gone. 这也解释了一个经典的 C 语言 bug: 返回一个指向局部数组的指针, 调用者拿到的地址,里面的内容早已不在了。
Malloc asks the heap for a block and hands back a pointer to it. malloc 向堆申请一块内存,然后交回一个指向它的指针。
The number you pass is a count of bytes, not of items — write malloc of three and you get three bytes, which is not enough for even one int. 你传进去的数字是字节数,不是元素个数—— 写 malloc(3) 你得到的是三个字节,连一个 int 都装不下。
So you say how many items you want times how big one is, and sizeof supplies the second half on whatever machine this runs on. 所以你要写“想要多少个”乘以“一个有多大”, 而 sizeof 会在这台机器上替你补上后半截。
Once you have the pointer, you index it just like an array. 拿到指针之后,你就像用数组一样用下标访问它。
Heap memory is borrowed, and free hands the block back. 堆内存是借来的,free 把这块内存还回去。
If nothing ever does, the program leaks that memory — it holds space it will never use again, and a long-running program that leaks steadily will eventually fall over. 如果始终没人还,程序就会泄漏这块内存—— 它占着一块再也不会用的空间, 一个长期运行、又持续泄漏的程序,最终会撑不住。
Two rules follow. 由此有两条规则。
Never touch the memory after you free it. 释放之后绝不要再碰这块内存。
And free it exactly once. 而且只释放一次。
In this lesson's tasks your function allocates and returns, and the checker frees it, so do not call free yourself. 在这一课的题目里,你的函数负责申请并返回,检查器负责释放, 所以你自己不要调用 free。
The third task grows an array by one, which is what realloc is for. 第三道题要把数组扩大一个元素,这正是 realloc 的用途。
It keeps the old contents, and there is one detail that decides whether your code works: it may move the block somewhere else entirely to find the room. 它会保留原有的内容, 而有一个细节决定了你的代码能不能用: 为了腾出空间,它可能把这块内存整个挪到别处去。
If you call it and ignore what it returns, your old pointer now points at memory that is no longer yours. 如果你调用了它却不理会返回值, 你原来那个指针指向的就是一块不再属于你的内存了。
So always assign the result back. 所以一定要把结果赋回去。
Four things to take with you. 带走四点。
One: heap memory outlives the function that asked for it. 第一:堆内存比申请它的那个函数活得更久。
Two: malloc counts bytes, so always multiply by sizeof. 第二:malloc 数的是字节,所以一定要乘上 sizeof。
Three: whoever owns the block frees it, exactly once. 第三:谁拥有这块内存谁负责释放,而且只释放一次。
Four: realloc may move the block, so take its return value. 第四:realloc 可能会搬走这块内存,所以要接住它的返回值。
Now do the three tasks; the second one allocates room for both arrays and copies them in. 现在去做那三道题; 第二题要为两个数组一起申请空间,再把它们拷贝进去。

Log in or create account

IGCSE, A-Level & AP