在學習函數 sbrk()
的時候,我們知道:
void *sbrk (intptr_t increment);
- 當 increment 爲正時,則按 increment 的大小,開闢內存空間,並返回開闢前,程序中斷點(program break)的地址。
- 當 increment 爲負時,則按 increment 的大小,釋放內存空間,並返回釋放前,程序中斷點的地址。
- 當 increment 爲零時,不會分配或釋放空間,返回當前程序中斷點的地址。
那麼寫一下測試代碼,【示例一】:
#include <unistd.h>
#include <stdio.h>
int main() {
printf("sbrk(0) = %p\n", sbrk(0)); // 應該返回 x
printf("sbrk(0) = %p\n", sbrk(0)); // 應該返回 x
printf("sbrk(5) = %p\n", sbrk(5)); // 應該返回 x
printf("sbrk(0) = %p\n", sbrk(0)); // 應該返回 x + 5
return 0;
}
預期得到類似這樣的結果:
sbrk(0) = 0x1985000
sbrk(0) = 0x1985000
sbrk(5) = 0x1985000
sbrk(0) = 0x1985005
但是輸出卻是這樣的:
sbrk(0) = 0x1985000
sbrk(0) = 0x19a6000
sbrk(5) = 0x19a6000
sbrk(0) = 0x19a6005
換一個寫法,將地址存儲在變量中,【示例二】:
#include <unistd.h>
#include <stdio.h>
int main() {
void *toto1 = sbrk(0);
void *toto2 = sbrk(0);
void *toto3 = sbrk(5);
void *toto4 = sbrk(0);
printf("sbrk(0) = %p\n", toto1);
printf("sbrk(0) = %p\n", toto2);
printf("sbrk(5) = %p\n", toto3);
printf("sbrk(0) = %p\n", toto4);
}
輸出結果:
sbrk(0) = 0x617000
sbrk(0) = 0x617000
sbrk(5) = 0x617000
sbrk(0) = 0x617005
這纔是我們預想的一樣,那爲什麼會出現這種情況呢?
其實出現這個問題的原因:是 printf 的鍋!
【示例一】的代碼,爲什麼前兩次調用
sbrk(0)
沒有返回相同的值?
在第一次調用printf
函數時,內部分配一個緩衝區stdout
,創建緩衝器的時候調用了malloc
,而malloc
內部又調用了brk
分配內存。【示例一】的代碼,爲什麼後面再多次調用
printf
沒有產生變化?
這是因爲,默認情況下,stdout
是行緩衝,並且緩衝區是在第一次打印時按需創建的,後面不論多少次調用printf
,緩衝區都已完成創建。【示例二】的代碼,爲什麼輸出是正確的?
sbrk
在printf
之前調用,因此,其他函數的malloc
是在分配空間之後進行,不會對輸出結果造成影響。