上次講到,如果在VC的console程序中,入口不為mainCRTStartup,會出現什麼後果?
我們就先將入口設置為main函數。
1 #include <stdio.h>2 3 int main()4 {5 printf("hello world
");6 return 0;7 }
先通過GUI來設置一下,創建一個win32 console Application。
代碼還是差不多,打印字符串
編譯鏈接運行,當然沒問題。
修改入口,在”project”->”setting”出現的對話框中,Link選項中,在”Entry-point symbol”中輸入main。即定義好入口為main函數。
Rebuild,編譯鏈接,沒有問題。
Deleting intermediate files and output files for project Hello - Win32 Debug.
--------------------Configuration: Hello - Win32 Debug--------------------
Compiling...
main.cpp
Linking...
Hello.exe - 0 error(s), 0 warning(s)
運行,出現問題。
來看一下到底是哪裡出現了問題。
運行debug版本,切到出錯部分。VC界面為:
不知道大家有沒有看得清楚,我將call stack單獨列在這裡,也就是上圖中標紅線的部分。
NTDLL! 7c9100e8()
_heap_alloc_base(unsigned int 0x00001030) line 161
_heap_alloc_dbg(unsigned int 0x00001000, int 0x00000002, const char * 0x00420c1c `string, int 0x0000003b) line 367 + 9 bytes
_nh_malloc_dbg(unsigned int 0x00001000, int 0x00000000, int 0x00000002, const char * 0x00420c1c `string, int 0x0000003b) line 242 + 21 bytes
_malloc_dbg(unsigned int 0x00001000, int 0x00000002, const char * 0x00420c1c `string, int 0x0000003b) line 163 + 27 bytes
_getbuf(_iobuf * 0x00422a58) line 59 + 19 bytes
_flsbuf(int 0x00000068, _iobuf * 0x00422a58) line 153 + 9 bytes
write_char(int 0x00000068, _iobuf * 0x00422a58, int * 0x0012fd10) line 1083 + 75 bytes
_output(_iobuf * 0x00422a58, const char * 0x0042001d, char * 0x0012ff74) line 393 + 21 bytes
printf(const char * 0x0042001c `string) line 60 + 18 bytes
main() line 5 + 10 bytes
KERNEL32! 7c817077()
可以看到,出錯部分是在NTDLL中的某個匯編代碼中,但是根源是在printf,printf調用到這部分的時候,結果在_heap_alloc_base的時候出錯了,_heap_alloc_base從字面意義上面就可以看出是在堆上分配內存的。
從上面一章,我們又可以得到mainCRTStartup函數在main函數之前調用,其中做了很多初始化工作,其中有一個函數調用叫做_heap_init,是用來創建和初始化CRT堆。而如果直接用main來做入口的話,則沒有做這些init工作。
剛剛是通過GUI來創建的,而通過命令行,前面cl編譯是一樣的,link的時候使用
1 d: est>link /entry:main hello.obj
2 Microsoft (R) Incremental Linker Version 6.00.8168
3 Copyright (C) Microsoft Corp 1992-1998. All rights reserved.同樣的效果。
另外,如果不用main,用另外一個函數,比如myentry,會出現什麼情況呢?你可以先試試,下一篇來具體說明一下~