MFC中程序没有错但为什么运行不了 C++ MFC程序,新建了一个MFC工程,能够编译通过,运行...

C++ MFC\u7a0b\u5e8f\u7f16\u8bd1\u6ca1\u6709\u95ee\u9898\uff0c\u4f46\u662f\u70b9\u8fd0\u884c\u5374\u6ca1\u6709\u5f39\u7a97\u51fa\u73b0\uff1f

\u4f60\u8d34\u7684\u8fd9\u884c\u4e0d\u662f\u9519\u8bef\uff0c\u5b83\u7684\u610f\u601d\u662f\u8bf4\uff0c\u8fd9\u4e2aDLL\u4e2d\u4e0d\u5305\u542b\u8c03\u8bd5\u4fe1\u606f\uff0c\u5373\u8fd9\u4e2aDLL\u5e76\u975eDEBUG\u7248\u3002
\u4e3b\u8981\u7684\u95ee\u9898\u662f\u540e\u9762\u90a3\u53e5 Fault \u7684\u9519\u8bef\uff0c\u662f\u8bf4\u524d\u9762\u51fa\u73b0\u4e86\u5806\u6808\u9519\u8bef\uff0c\u7a0b\u5e8f Crash \u4e86\uff0c\u4f60\u5f97\u627e\u627e\u521d\u59cb\u5316\u90e8\u5206\u7684\u4ee3\u7801\uff0c\u54ea\u91cc\u5bfc\u81f4\u4e86\u7a0b\u5e8f\u5d29\u6e83\u3002

\u4e0d\u77e5\u9053\u4e3a\u4ec0\u4e48\uff0c\u4f60\u53ef\u4ee5\u5728vs\u7684\u547d\u4ee4\u884c\u5de5\u5177\u91cc\uff0c\u6267\u884c\u4e0b\u9762\u76845\u6b65\uff0c\u751f\u6210\u4e00\u4e2avsp\u62a5\u544a\u6587\u4ef6\uff0c\u91cc\u9762\u4f1a\u544a\u8bc9\u4f60\u8be6\u7ec6\u4fe1\u606f\u3002
1.VSPerfCLREnv /sampleon (to set proper environment variables)
2.VsPerfCmd /start:sample /output:reportFile.vsp /launch:\ServerFrame.exe
3.Run your application to collect sample data
4.VSPerfCmd /shutdown (to shut down the profiler)
5.VSPerfReport \reportFile.vsp /output: /summary:all

哪些情况下 Release 版会出错

有了上面的介绍,我们再来逐个对照这些选项看看 Release 版错误是怎样产生的

1. Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的 Runtime Library 通常很稳定,不会造成 Release 版错误;倒是由于 Debug 的 Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现 Debug 有错但 Release 正常的现象。应当指出的是,如果 Debug 有错,即使 Release 正常,程序肯定是有 Bug 的,只不过可能是 Release 版的某次运行没有表现出来而已。

2. 优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:

(1) 帧指针(Frame Pointer)省略(简称 FPO ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误 ————但 Debug 方式下,栈的访问通过 EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略 EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在 Release 版本中强制加入 /Oy- 编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:

● MFC 消息响应函数书写错误。正确的应为
afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);
ON_MESSAGE 宏包含强制类型转换。防止这种错误的方法之一是重定义 ON_MESSAGE 宏,把下列代码加到 stdafx.h 中(在#include "afxwin.h"之后),函数原形错误时编译会报错
#undef ON_MESSAGE
#define ON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_lwl, \
(AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \
CWnd::*)(WPARAM, LPARAM) > (&memberFxn) },

(2) volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于 register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确 的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上 volatile 试试。

(3) 变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在 Debug 版中它有可能掩盖一个数组越界,而在 Release 版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有:
● 非法访问,包括数组越界、指针错误等。例如
void fn(void)
{
int i;
i = 1;
int a[4];
{
int j;
j = 1;
}
a[-1] = 1;//当然错误不会这么明显,例如下标是变量
a[4] = 1;
}
j 虽然在数组越界时已出了作用域,但其空间并未收回,因而 i 和 j 就会掩盖越界。而 Release 版由于 i、j 并未其很大作用可能会被优化掉,从而使栈被破坏。

3. _DEBUG 与 NDEBUG :当定义了 _DEBUG 时,assert() 函数会被编译,而 NDEBUG 时不被编译。除此之外,VC++中还有一系列断言宏。这包括:

ANSI C 断言 void assert(int expression );
C Runtime Lib 断言 _ASSERT( booleanExpression );
_ASSERTE( booleanExpression );
MFC 断言 ASSERT( booleanExpression );
VERIFY( booleanExpression );
ASSERT_VALID( pObject );
ASSERT_KINDOF( classname, pobject );
ATL 断言 ATLASSERT( booleanExpression );
此外,TRACE() 宏的编译也受 _DEBUG 控制。

所有这些断言都只在 Debug版中才被编译,而在 Release 版中被忽略。唯一的例外是 VERIFY() 。事实上,这些宏都是调用了 assert() 函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用 等),那么 Release 版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入 #ifdef _DEBUG 之类的条件编译,也要注意一下。
顺便值得一提的是 VERIFY() 宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查 Windows API 的返回值。有些人可能为这个原因而滥用 VERIFY() ,事实上这是危险的,因为 VERIFY() 违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。

4. /GZ 选项:这个选项会做以下这些事

(1) 初始化内存和变量。包括用 0xCC 初始化所有自动变量,0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如 new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如 delete ),0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且 32 位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在 Debug 版中发现 Release 版才会遇到的错误。要特别注意的是,很多人认为编译器会用 0 来初始化变量,这是错误的(而且这样很不利于查找错误)。
(2) 通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配)
(3) 函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略 FPO )

通常 /GZ 选项会造成 Debug 版出错而 Release 版正常的现象,因为 Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。

除此之外,/Gm /GF 等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。
--------------------------------------------------------------
Release是发行版本,比Debug版本有一些优化,文件比Debug文件小
Debug是调试版本,包括的程序信息更多
Release方法:
build->batch build->build就OK.

具体可以看看下面的链接

楼主看看任务管理器,能找到相应的进程吗,可能是没有窗口的,可能是你注释代码时把显示窗口的代码注释掉了
再就是func7说的调试跟踪程序了

编译没错误不代表运行会正确。。。
差错的话可以调试跟踪程序看看运行到哪里出错了

你是不是没有显示出来哦。。就是对话框没有调用显示函数的。
你仔细看看的

  • ...浣跨敤MFC缂栧啓鐨勭▼搴,debug娌℃湁閿欒,鑰宺elease杩愯鐨勬椂鍊欐湁閿欒鎬庝箞鍥...
    绛旓細浣犺繖涓幇璞″緢姝e父锛孌EBUG妯″紡绋嬪簭姝g‘涓嶄繚璇丷elease姝g‘锛鍥犱负DEBUG妯″紡鍦ㄧ▼搴忎腑鎻掑叆浜嗚澶氳皟璇曠敤鐨勪俊鎭紝鍐呭瓨鐨勭粨鏋勫拰release鐗堟湰鏄笉涓鏍风殑锛屼綘鐨勮繖涓敊璇槸鍐呭瓨璁块棶瓒婄晫浜嗭紝瑕佹鏌ュ唴瀛樹娇鐢ㄦ儏鍐碉紝鏄惁鏈夌┖鎸囬拡锛屾暟缁勭储寮曡秺鐣岋紝鎴栦娇鐢˙oundCheck绛夊唴瀛樻鏌ュ伐鍏枫
  • MFC涓▼搴忔病鏈夐敊浣嗕负浠涔堣繍琛涓嶄簡
    绛旓細搴斿綋鎸囧嚭鐨勬槸锛屽鏋 Debug 鏈夐敊锛屽嵆浣 Release 姝e父锛岀▼搴忚偗瀹氭槸鏈 Bug 鐨勶紝鍙笉杩囧彲鑳芥槸 Release 鐗堢殑鏌愭杩愯娌℃湁琛ㄧ幇鍑烘潵鑰屽凡銆2. 浼樺寲锛氳繖鏄犳垚閿欒鐨勪富瑕佸師鍥狅紝鍥犱负鍏抽棴浼樺寲鏃舵簮绋嬪簭鍩烘湰涓婃槸鐩存帴缈昏瘧鐨勶紝鑰屾墦寮浼樺寲鍚庣紪璇戝櫒浼氫綔鍑轰竴绯诲垪鍋囪銆傝繖绫婚敊璇富瑕佹湁浠ヤ笅鍑犵锛(1) 甯ф寚閽(Frame Pointer...
  • MFC缂栬瘧杩愯娌閿,浣嗚繍琛EXE鍑洪敊
    绛旓細璁剧疆鏂偣璋冭瘯涓嬶紝浼拌鏄唴瀛橀敊璇锛屽啓寰椾唬鐮佹湁闂 浣犲湪璇绘枃浠跺墠锛屽皢璺緞杈撳嚭鐪嬬湅锛岀湅鏄惁鏄矾寰勬湁闂銆
  • 鍏充簬MFC缂栬瘧杩炴帴娌℃湁閿欒,鎵ц娌″弽搴旀垨鑰呭嚭閿鐨闂!
    绛旓細杩欎釜搴旇鏄帶浠堕儴鍒嗗嚭閿.濡傛灉鏄竴涓璇濇鐨勮瘽, 鍦―oDataExchange鍑芥暟涓瑿Dialog::DoDataExchange(pDX);鍚庨潰鐨勫彞瀛愪竴琛屼竴琛岀殑娉ㄩ噴鍐嶈繍琛, 鐪嬫槸鍝竴琛屾敞閲婂悗涓嶅嚭閿, 鍒欒鎺т欢鍒濆鍖栨湁闂.
  • 鍦∕FC(C++)涓畾涔変簡涓涓叏灞缁撴瀯浣,鍦ㄥ叾浠栧嚱鏁颁腑鐢ㄨ繖涓粨鏋勪綋,缂栬瘧璋 ...
    绛旓細杩欎釜鏀鹃敊浜嗕綅瀛愶紝鍦╟ourse.h澶存枃浠閲鍙渶瑕佸0鏄庣粨鏋勪綋鍗冲彲锛屽湪course.cpp涓畾涔夛紝杩欐牱涓涓畬鏁鐨缁撴瀯浣撳氨鎴愬姛浜嗐備綘鐨勬兂娉曞簲璇ユ槸鎯冲湪course.cpp浠ュ鐨勬枃浠朵腑璋冪敤缁撴瀯浣搒ong锛岃繖涓椂鍊欏湪浣犻渶瑕佽皟鐢 song aa[5]鐨勬枃浠朵腑澹版槑extern song aa[5]鍗冲彲銆傚綋鐒跺垏璁伴渶瑕佸皢course.h鍖呭惈杩涙潵銆傚笇鏈涜兘甯埌浣......
  • MFC 绋嬪簭缂栬瘧娌℃湁閿欒 杩愯鏃堕鍑 DEBUG鏃跺唴瀛樹笉鑳戒负READ 閫鍑
    绛旓細鑰屼竴鏃﹀唴瀛樺彂鐢熼棶棰樹簡锛岀▼搴忓氨涓嶈兘琚墽琛岋紝鍥犳灏变骇鐢熶簡鍓嶉潰鎴戜滑鎻愬埌鐨勨滆鍐呭瓨涓嶈兘涓簉ead鎴杦ritten鈥閿欒鐨勮鍛娿傚綋鐒讹紝鍑虹幇浜嗏滆鍐呭瓨涓嶈兘涓簉ead鎴杦ritten鈥濈殑鏁呴殰涔熶笉涓瀹氶兘鏄唴瀛樼殑闂锛岀數鑴戜腑浜嗙梾姣掓垨鏈ㄩ┈浠ュ強杩愯鐨勭▼搴鏈韩鐨凚ug涔熶細閫犳垚杩欑鐜拌薄銆傚緢闅惧垎娓呯┒绔熸槸浠涔堝師鍥犻犳垚鐨勶紝涓鏃跺崐浼氫笉濂芥帓闄...
  • MFC鍗曟枃妗绋嬪簭,缂栬瘧閾炬帴閮娌℃湁閿,鑳杩愯,杩愯瀹屽叧闂璇濇鍚庡脊鍑哄涓嬪...
    绛旓細缂栬瘧閫氳繃浜 涓嶄竴瀹氭纭 鍙兘鏄綘娌¤瀵硅瘽妗嗘樉绀 浣犳壘涓纭殑渚嬪瓙 瀵圭潃鐪嬬湅
  • mfc鐨杈撳嚭鏁版嵁搴撴煡璇㈢殑缁撴灉鐨勯棶棰,浠g爜濡備笅,璋冭瘯娌¢敊,浣嗘槸杩愯鍚,閭d釜...
    绛旓細杩欐浠g爜涓婃病鐪嬪嚭鏈夐棶棰橈紝UpdateData鐢ㄥ浜嗭紙涔熺敤澶氫簡锛夛紝濡傛灉璁板綍闆嗘病闂锛岄偅涔堝簲璇ユ槸ok鐨銆傚湪m_myshowlist.AddString(str);璁剧疆鏂偣锛孎5璋冭瘯涓涓嬪惂锛屼及璁_pSet鐨勬搷浣滃彲鑳戒笉瀵癸紝鎴栬鏍规湰涓嶈繘鍏ュ惊鐜傚浜嗭紝if(m_pSet->m_studentnum==m_xsnum)涔嬪墠鏈濂藉鐞嗕竴涓嬪瓧绗︿覆銆傚彟澶栵紝浠g爜鏁堢巼浼氬緢浣庯紝...
  • MFC鏃犳硶杩愯鐨鍘熷洜?鎴鍦∕FC涓鍔犲叆浜嗕竴涓狢WebBrowser鐨勬帶浠跺悗,杩愯娌℃湁...
    绛旓細鍒犻櫎鎵鏈夌洰鏍囨枃浠跺悗鍐嶆缂栬瘧杩愯灏辨甯镐簡銆傝繖涓簲璇ユ槸vc鐨勯棶棰橈紝涓嶆槸鎮鐨勯敊銆
  • MFC涓,鎴戞垚鍔熷鍏ヤ簡CBUTTONSt绫,杩愯鍚庢渶鍚庢寜閽篃鑳芥樉绀,浣嗘槸鍑虹幇浜嗕笉...
    绛旓細杩欎釜鏄柇瑷閿欒锛屼唬琛ㄤ綘鐨勭▼搴閲鏈涓昏緫閿欒銆備綘鐨MFC寮曞彂浜唚incore.cpp鏂█锛屾垜閬囧埌鐨勬儏鍐垫槸鍦ㄥ瓙绐楀彛鍒涘缓鏃讹紝鎷︽埅浜嗙埗绐楀彛鐨勫垱寤烘秷鎭紝瀵艰嚧杩欎釜寮傚父鎶涘嚭銆備綘妫鏌ヤ笅浣犵殑绐楀彛鍒涘缓浠g爜閮ㄥ垎鏄笉鏄湁鍙枒鐨勫姩浣滐紵
  • 扩展阅读:手机nfc使用方法 ... 有nfc就能无线充电吗 ... 电脑显示mfc140udll丢失 ... mfc140 dll为什么会丢失 ... 手机闪付nfc怎么用 ... mfc140u dll为啥会丢失 ... 失败原因cds.mf13 ... win10检测不到打印机 ... 手机mfc功能怎么用 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网