推 handsome616:超強.... 03/10 17:34
不是在說明 overloaded operator new, c++ 書籍應該都會提到。
本範例是作業系統等級的程式碼, 在完成了 global/static object 的研究之後, 來
看看怎麼實作 new/delete, 在 c++ 若不能使用 new/delete, 好像說不過去。
測試方式:
在 linux compile 成 dos .com 檔, 然後放到 qemu/dos 上執行。
no_impl_new_delete.cpp
1 __asm__(".code16gcc\n");
2 #include "io.h"
3 #include "obj.h"
4
5 typedef signed char s8;
6 typedef signed short s16;
7 typedef signed int s32;
8
9 typedef unsigned char u8;
10 typedef unsigned short u16;
11 typedef unsigned int u32;
12
13 #define BOCHS_MB __asm__ __volatile__("xchg %bx, %bx");
14
15 extern int _start_ctors;
16 extern int _end_ctors;
17
18 void s16_print_int(int i, int radix);
19 void print_str(const char *s);
20
21 extern int obj_count;
22
23
24 const int SOME_BASE_ADDRESS = 0x500;
25
26 void myfree(void *ptr)
27 {
28 print_str("myfree\r\n");
29 }
30
31 void *mymalloc(int size)
32 {
33 print_str("size: ");
34 s16_print_int(size, 10);
35 print_str("\r\n");
36 static char mem[256];
37 return mem;
38 }
39
52
53 extern "C" int cpp_main(void)
54 {
55 print_str("cpp_main\r\n");
56 s16_print_int(obj_count, 10);
57 print_str("\r\n");
58
59 Io *io_p = new Io;
60 const char *ver=__VERSION__;
61 io_p->print("io_p g++ version: ");
62 io_p->print(ver);
63 io_p->print("\r\n");
64 delete io_p;
65
66 return 0;
67 }
L59 和我們平常使用的 c++ new 用法一模一樣, new 會做類似 malloc 的動作, 先去要
一塊記憶體, 並呼叫 ctor, 可是在作業系統之前的程式, 根本沒有記憶體管理的程式碼
(記得我們沒有 c++ runtime 來幫我們做這件事情嗎?), 來看看編譯會怎麼樣?
descent@debian-vm:dos_cpp$ make new_test.bin
ld -m elf_i386 -static -Tcpp.ld -nostdlib -M -o new_test.elf cpp_init.o
new_test.o io.o cpp_abi.o obj.o dos_io.o > new_test.elf.map
new_test.o: In function `cpp_main':
/home/descent/git/simple_os/cpp_runtime/global_object/dos_cpp/new_test.cpp:59:
undefined reference to `operator new(unsigned int)'
/home/descent/git/simple_os/cpp_runtime/global_object/dos_cpp/new_test.cpp:64:
undefined reference to `operator delete(void*)'
make: *** [new_test.elf] Error 1
呵呵, 果然有預期的錯誤, 要是沒錯誤反而令我害怕。訊息很容易理解, 沒定義
operator new, operator delete, 所以該怎麼辦? 不難, 自己定義就好了。
new_test.cpp L41 ~ L49 就提供了 operator new, operator delete, 比想像中還要簡
單吧! 這時候再編譯就沒問題了。有問題的是那個 mymalloc 要怎麼寫是吧?
這個的確是個問題, 得先搞定記憶體管理才能把這部份寫好, 一開始也困擾我許久, 因為
我這部份還沒做得很好, 不過我只想搞定 c++ runtime new/delete,
並不是要實作記憶體管理機制 (這個就不容易了), 所以想了個簡單的辦法來模擬
malloc 的行為。
L26, L31 的 mymalloc/myfree 應該很簡單, 簡單到不用說明吧?
new_test.cpp
1 __asm__(".code16gcc\n");
2 #include "io.h"
3 #include "obj.h"
4
5 typedef signed char s8;
6 typedef signed short s16;
7 typedef signed int s32;
8
9 typedef unsigned char u8;
10 typedef unsigned short u16;
11 typedef unsigned int u32;
12
13 #define BOCHS_MB __asm__ __volatile__("xchg %bx, %bx");
14
15 extern int _start_ctors;
16 extern int _end_ctors;
17
18 void s16_print_int(int i, int radix);
19 void print_str(const char *s);
20
21 extern int obj_count;
22
23
24 const int SOME_BASE_ADDRESS = 0x500;
25
26 void myfree(void *ptr)
27 {
28 print_str("myfree\r\n");
29 }
30
31 void *mymalloc(int size)
32 {
33 print_str("size: ");
34 s16_print_int(size, 10);
35 print_str("\r\n");
36 static char mem[256];
37 return mem;
38 }
39
40 // ref:http://goo.gl/T39BU8
41 void *operator new(unsigned int s)
42 {
43 return mymalloc(s);
44 }
45
46 void operator delete(void *p)
47 {
48 myfree(p);
49 }
50
51 extern "C" int cpp_main(void)
52 {
53 print_str("cpp_main\r\n");
54 s16_print_int(obj_count, 10);
55 print_str("\r\n");
56
57 Io *io_p = new Io;
58 const char *ver=__VERSION__;
59 io_p->print("io_p g++ version: ");
60 io_p->print(ver);
61 io_p->print("\r\n");
62 delete io_p;
63
64 return 0;
65 }
L57 new 發動時, L41 operator new 會被 c++ 編譯器傳入正確的 class size, 在 Io
class 這個例子, size 是 4, 下圖便是在 dos 下的執行結果。
( http://goo.gl/ov3WhK )
比起 global/static object, operator new/delete 簡單到令我驚訝 (當然, 真的要處
理記憶體的分配與回收就沒那麼簡單了)。所以在作業系統之下寫 c++ 程式,
c++ runtime library 做了不少辛苦的事情。
source code:
https://github.com/descent/simple_os ( http://goo.gl/XDC9Iq )
commit 93e327234d153636e315721ca66f73df0e7c0887
cpp_runtime branch
ref: http://wiki.osdev.org/C%2b%2b#The_Operators_.27new.27_and_.27delete.27
//
本文使用 Blog2BBS 自動將Blog文章轉成縮址的BBS純文字
http://blog2bbs.herokuapp.com/index.php
//
blog 原文:
http://descent-incoming.blogspot.tw/2013/12/operator-newdelete.html
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 119.14.102.134