谁帮我解释一下assert的问题 我的程序运行时出现 debug assertion failed,为什么会造成这种错呢? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 afxwin1.ini如果是这个错误,应该是你最新添加的代码造成的,尤其注意输入符号错误 还是先让楼主了解什么是ASSERT()先我同许多学生接触很多, 很好的了解他们的错误. 而且, 我也很了解我的错误. 有一种能使你的程序可信度更高. 它就是应用assertiong宏的陷阱(trap)技术. 下面描述了通常的C++技术和VC++/MFC特殊功能.1. 为什么必须将指针初始化为 NULL如果你有class A{public: A(); ~A(); //some declarations.private: SomeType* m_pPointer; //some declarations.};A::~A(){ delete m_pPointer;}如果你在构造函数之外给指针赋值, 你必须总是将它设为NULL. 例如:A::A():m_pPointer(NULL){}—为什么?—因为: 1). 如果你的程序执行的逻辑不为指针创建对象, delete操作将无错的执行(根据C++语言标准). 如果你忘了初始化bypass pointer, 它将有一个随机值, 对这个地址的删除将是你的程序崩溃. 2). 通过用断点和追踪, 你能够容易的找到没有初始化的指针. 3). 你可以用 "if" 操作来测试一个有效地指针, 如:if(m_pPointer){ m_pPointer->DoSomething();}else{ AfxMessageBox("Unexpected error #1234. Send me letter please to [email protected]");} 可能你的程序不能正确工作, 但是在这里它不会崩溃. 这是非常重要的. 想象你已经输入了两个小时文本并没有存盘. 你更希望文本编辑器崩溃呢还是给出一些警告? 4).你可以用ASSERT宏设置调试陷阱(debug trap)2. 为调试设的陷阱(Traps) 插入断点是一个好技术, 但是如果问题出在长的循环内部那就不是高效的了. 例如, 在10,000次循环之后,一些条件变的有问题了. 为了抓住这样的问题, VC++/MFC 程序员应用 ASSERT 宏. ANSI宏也经常被应用.用哪个不是问题, 在下面的例子中我用了 MFC ASSERT 宏. —它怎样被用?—这样:ASSERT(condition);例子:ASSERT(nWaterTemperature > 0 && nWaterTemperature < 100); // break if wrong valueASSERT(pSomePointer); // break if null pointerASSERT(0); // break if here—它怎样工作?—这样:断言(assertion)用带断言信息(程序, 模块, assertion行)的对话框执行. 对话框有3个按钮: "Break", "Repeat" ("Debug"), and "Continue" ("Ignore"). "Break" 结束程序, "Continue" 忽略断言, 最有用的是"Repeat"按钮. 按下它在断言的地方打开源代码编辑器. 在这里你可以测试所有的变量值并明白哪里出了问题.—它怎样用?—多数这样用:为了控制传进的指针:void SomeFun(SomeType* pPointer){ ASSERT(pPointer); //some instructions.}你可以在"switch" 和 "if"操作中捕获奇怪的值例如:switch(nRGBColors){ case nRed: {//some instructions.} break; case nGreen: {//some instructions.} break; case nBlue: {//some instructions.} break; default: ASSERT(0); // we should have never come here!}if(nWaterTemp >=0 && nWaterTemp < 50){ //some instructions.}else if(nWaterTemp >= 50 && nWaterTemp <= 100){ //some instructions.}else{ ASSERT(0); // we should have never come here!}对值的断言: ASSERT(nSomeValue >= MinValue and nSomeValue <= MaxValue);ASSERT(nOtherValue != 0);等.Always use this technique and you will be greatly surprised how often such traps will work!总是应用这个技术, 你将被how often这些陷阱将工作 大大震惊.3. 可爱的 ASSERT 错误ASSERT( m_MyWnd.Create() );呕! 这是一个可怕的错误! 程序在调试版中正常工作, 在发行版中不工作. 记住: 这是一个在发行版中将被移除的宏. 以这种方法你的窗口将永远不会被创建. 如果你用 MFC, 这样做:VERIFY( m_MyWnd.Create() );它在调试版中像ASSERT一样并且在发行版中执行m_MyWnd.Create()4. 对象验证及MFC宏ASSERT_VALID利用类的verify成员是众所周知的验证对象的技术. 如果你有明确的对象的验证条件, 你可以创建和利用verify类成员. 例如:class Time{public: void Set(int h, int m); bool Verify(){return m_h>=0 && m_h<24 and m_m>=0 && m_m<60; } //some instructions.};void Time::Set(int h, int m){ m_h = h; m_m = m; ASSERT(Verify());}大多数的MFC类是CObject的子类. 它有用来验证用的AssertValid虚函数 如果一个类实现了这个函数, 他被ASSERT_VALID宏调用. 例如:ASSERT_VALID(pView);它检查某个CViewWnd对象的指针. 如果对象无效(空指针或错的窗口句柄), 断言将被执行.5. MFC TRACE 宏没有TRACE宏描述的MFC宏的附录将是不调和的. 在主控台模式下用流输出变量的值是没有问题的. 从另一方面来讲, Windows下编程追踪变量并不是一个琐碎的任务.实际上, 当我们追踪某事时许多窗口可以被打开和关闭. 没有必要把追踪输出写到许多窗口上. 一个窗口足够了. 因为这个目的, VC++ IDE应用了"输出"窗口(View-Output menu point). 为了调试输出, 你可以利用TRACE操作符, 它同printf stdio函数具有相同的格式.例如:TRACE("\nThis is a trace of int variable %d.", nSomeInt);TRACE("\nFunction OnInitialUpdate is starting."); 请教FTP上传,进度条显示上传进度? vc复制Temporary Internet Files下文件问题 利用TCP\IP协议进行传输时,不是可以保证数据的有效性吗?为什么还要加上校验呢? 如何让根号3出现在下拉框中供客户选择? 代理服务器的问题 关于按钮重绘的问题..... pomelowu(羽战士)大哥还有100分 在进来一下了。 图形识别(抓拍的图片上有麻将面图,如何识别??请教高手不吝赐教!!!) 关于listcontrol查找 TCP 连接池的问题!高手快来拿100分吧! 想不通啊想不通! 欢迎提供信息
如果是这个错误,应该是你最新添加的代码造成的,尤其注意输入符号错误
如果你有class A{
public:
A();
~A();
//some declarations.
private:
SomeType* m_pPointer;
//some declarations.
};A::~A(){
delete m_pPointer;
}如果你在构造函数之外给指针赋值, 你必须总是将它设为NULL. 例如:A::A():m_pPointer(NULL){}—为什么?
—因为: 1). 如果你的程序执行的逻辑不为指针创建对象, delete操作将无错的执行(根据C++语言标准). 如果你忘了初始化bypass pointer, 它将有一个随机值, 对这个地址的删除将是你的程序崩溃.
2). 通过用断点和追踪, 你能够容易的找到没有初始化的指针.
3). 你可以用 "if" 操作来测试一个有效地指针, 如:
if(m_pPointer){
m_pPointer->DoSomething();
}
else{
AfxMessageBox("Unexpected error #1234. Send me letter
please to [email protected]");
}
可能你的程序不能正确工作, 但是在这里它不会崩溃. 这是非常重要的. 想象你已经输入了两个小时文本并没有存盘. 你更希望文本编辑器崩溃呢还是给出一些警告? 4).你可以用ASSERT宏设置调试陷阱(debug trap)2. 为调试设的陷阱(Traps) 插入断点是一个好技术, 但是如果问题出在长的循环内部那就不是高效的了. 例如, 在10,000次循环之后,一些条件变的有问题了. 为了抓住这样的问题, VC++/MFC 程序员应用 ASSERT 宏. ANSI宏也经常被应用.用哪个不是问题, 在下面的例子中我用了 MFC ASSERT 宏. —它怎样被用?
—这样:ASSERT(condition);
例子:ASSERT(nWaterTemperature > 0 &&
nWaterTemperature < 100); // break if wrong value
ASSERT(pSomePointer); // break if null pointer
ASSERT(0); // break if here—它怎样工作?
—这样:断言(assertion)用带断言信息(程序, 模块, assertion行)的对话框执行. 对话框有3个按钮: "Break", "Repeat" ("Debug"), and "Continue" ("Ignore"). "Break" 结束程序, "Continue" 忽略断言, 最有用的是"Repeat"按钮. 按下它在断言的地方打开源代码编辑器. 在这里你可以测试所有的变量值并明白哪里出了问题.—它怎样用?
—多数这样用:为了控制传进的指针:
void SomeFun(SomeType* pPointer)
{
ASSERT(pPointer);
//some instructions.
}你可以在"switch" 和 "if"操作中捕获奇怪的值
例如:switch(nRGBColors){
case nRed: {//some instructions.} break;
case nGreen: {//some instructions.} break;
case nBlue: {//some instructions.} break;
default: ASSERT(0); // we should have never come here!
}if(nWaterTemp >=0 && nWaterTemp < 50){
//some instructions.
}
else if(nWaterTemp >= 50 && nWaterTemp <= 100){
//some instructions.
}
else{
ASSERT(0); // we should have never come here!
}对值的断言:
ASSERT(nSomeValue >= MinValue and nSomeValue <= MaxValue);
ASSERT(nOtherValue != 0);
等.Always use this technique and you will be greatly surprised how often such traps will work!
总是应用这个技术, 你将被how often这些陷阱将工作 大大震惊.3. 可爱的 ASSERT 错误
ASSERT( m_MyWnd.Create() );呕! 这是一个可怕的错误! 程序在调试版中正常工作, 在发行版中不工作. 记住: 这是一个在发行版中将被移除的宏. 以这种方法你的窗口将永远不会被创建. 如果你用 MFC, 这样做:VERIFY( m_MyWnd.Create() );它在调试版中像ASSERT一样并且在发行版中执行m_MyWnd.Create()4. 对象验证及MFC宏ASSERT_VALID
利用类的verify成员是众所周知的验证对象的技术. 如果你有明确的对象的验证条件, 你可以创建和利用verify类成员.
例如:class Time
{
public:
void Set(int h, int m);
bool Verify(){return m_h>=0 && m_h<24 and m_m>=0 && m_m<60; }
//some instructions.
};void Time::Set(int h, int m)
{
m_h = h;
m_m = m;
ASSERT(Verify());
}
大多数的MFC类是CObject的子类. 它有用来验证用的AssertValid虚函数 如果一个类实现了这个函数, 他被ASSERT_VALID宏调用. 例如:
ASSERT_VALID(pView);它检查某个CViewWnd对象的指针. 如果对象无效(空指针或错的窗口句柄), 断言将被执行.5. MFC TRACE 宏没有TRACE宏描述的MFC宏的附录将是不调和的. 在主控台模式下用流输出变量的值是没有问题的. 从另一方面来讲, Windows下编程追踪变量并不是一个琐碎的任务.实际上, 当我们追踪某事时许多窗口可以被打开和关闭. 没有必要把追踪输出写到许多窗口上. 一个窗口足够了. 因为这个目的, VC++ IDE应用了"输出"窗口(View-Output menu point). 为了调试输出, 你可以利用TRACE操作符, 它同printf stdio函数具有相同的格式.例如:TRACE("\nThis is a trace of int variable %d.", nSomeInt);
TRACE("\nFunction OnInitialUpdate is starting.");