to yuanwh(yuanwh): 你试试这个,看看你的try/catch起作用了吗: try { char *p = NULL; p[100] = 'a'; } catch(...) { ...... }试过了,当然起作用了,程序运行时除了弹出我自己指定的消息框外,看起来一点异常都没有,我在VC6底下试,不过我相信其它编译应该是一样的,因为try/catch机制其实是挂接了系统中断向量,与用什么编译器无关. 这就是我的测试代码 BOOL CTestcallDlg::OnInitDialog() { try { char *p = NULL; p[100] = 'a'; } catch(...) { AfxMessageBox("I catch an error"); } CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control }
to yuanwh(yuanwh): your are right! 我低估了try/catch的能力:) 只能说我的例子举得不好,并不能说明try/catch什么都能抓。
to yuanwh(yuanwh): 我又试了一下,你的代码,在debug下可以,在release下你试试。 VC的debug版本是很强壮的。 差点被你们搞胡涂:)
to pcman1990(pcman): 真的很多谢你的关注。不过我最奇怪是为什么在call stack里看到的全是系统的DLL而完全没有属于我自己的函数,是不是说明调用堆栈已乱套了?我记得以前DOS时代的BorlandC++ 3.1有一个compile选项是可以帮程序员自动生成保护堆栈的代码,不知现在VC有没有类似的选项。不知你有没有接触过这方面的问题。
try/catch rely on the capability of stack unwinding, if stack is corrupted, try/catch also fail. Eg. try { char p[10]; for(int i=0;;i++) { p[i]=0; }
} catch(...) { printf("I catch an exception in second part"); } the catch does not work at all.
to pcman1990(pcman): 在release不行并不是因为try/catch这一机制有问题,而是被VC的编译器在release的默认方式下去掉了对try/catch的编译。况且我原来运行的程序也是debug版本的!
{
...//其它函数的调用
}
catch(...) // ...是默认为获取所有类型错误,当然这也可定义错误类型
{
...//异常处理
}
按道理这样做,当程序出现异常时会执行你的异常处理,但有点我要提醒你
在你执行其它函数的调用时,这其它函数本身内部可能出现了异常,所以导
导错误信息,显示程序企图执行地址在00000000处的代码,换句话说:
其它函数内出现的异常,只能由它本身来捕获和执行,本函数是无法
捕获和处理的(它只捕获其内部语句的错误)。要不你调试跟踪进出试试!
请注意,try/catch不是万能的,并不是说你的代码产生的错误都能捕捉,正确的理解是这样的:只有你程序中抛出的错误,才能被catch。举个简单的例子:
try
{
char *p = new char(nCount);
p->...... // 如果此时,new操作失败,p = NULL,那么这种情况下,这句照样要引起系统错误,而try/catch是没有作用的。
}
catch(...)
{
......
}只有这样,你才能捕捉到这个错:
try
{
char *p = new char(nCount);
if(p == NULL) throw -1; // !!!
p->......
}
catch(...)
{
......
}
也就是说,try/catch只是提供一个处理exception的机制,本身并不负责捕捉错误。
谢了!还有楼长
{
char *p = new char(nCount);
p->...... // 如果此时,new操作失败,p = NULL,那么这种情况下,这句照样要引起系统错误,而try/catch是没有作用的。
}
catch(...)
{
......
}好象不对吧!我在VC下专门试过这样用法,运行时没有问题啊!
捕获和处理的(它只捕获其内部语句的错误)。这种说法也不对。我专门在其它函数中造了个除0错的语句,照样能捕捉到的。
我最奇怪是为什么在call stack里看到的全是系统的DLL而完全没有属于我自己的函数,是不是说明调用堆栈已乱套了?我记得以前DOS的BorlandC++ 3.1有一个compile选项是可以帮程序员自动生成保护堆栈的代码,不知现在VC有没有类似的选项。
你试试这个,看看你的try/catch起作用了吗:
try
{
char *p = NULL;
p[100] = 'a';
}
catch(...)
{
......
}
>> p[100] = 'a';
这有什么错呀?!p[10000] = 'a';这样又能怎么样呢?!
你试试这个,看看你的try/catch起作用了吗:
try
{
char *p = NULL;
p[100] = 'a';
}
catch(...)
{
......
}试过了,当然起作用了,程序运行时除了弹出我自己指定的消息框外,看起来一点异常都没有,我在VC6底下试,不过我相信其它编译应该是一样的,因为try/catch机制其实是挂接了系统中断向量,与用什么编译器无关.
这就是我的测试代码
BOOL CTestcallDlg::OnInitDialog()
{
try {
char *p = NULL;
p[100] = 'a';
} catch(...) {
AfxMessageBox("I catch an error");
}
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
your are right! 我低估了try/catch的能力:) 只能说我的例子举得不好,并不能说明try/catch什么都能抓。
我又试了一下,你的代码,在debug下可以,在release下你试试。
VC的debug版本是很强壮的。
差点被你们搞胡涂:)
真的很多谢你的关注。不过我最奇怪是为什么在call stack里看到的全是系统的DLL而完全没有属于我自己的函数,是不是说明调用堆栈已乱套了?我记得以前DOS时代的BorlandC++ 3.1有一个compile选项是可以帮程序员自动生成保护堆栈的代码,不知现在VC有没有类似的选项。不知你有没有接触过这方面的问题。
try
{
char p[10];
for(int i=0;;i++)
{
p[i]=0;
}
}
catch(...)
{
printf("I catch an exception in second part");
}
the catch does not work at all.
在release不行并不是因为try/catch这一机制有问题,而是被VC的编译器在release的默认方式下去掉了对try/catch的编译。况且我原来运行的程序也是debug版本的!
你的说法比较有道理。我也是怀疑堆的问题,但不知用什么办法侦测到底是哪里出的问题,我对凡是有memcpy,strcpy等类似的地方都仔细检查过,但好象都没有发现什么错,真不知怎么办。期待你的回复!
>release的默认方式下去掉了对try/catch的编译。况且我原来运行的程序也
>是debug版本的!
但是,release下你试试:
try
{
throw -1;
}
catch(...)
{
......
}