C++ assert(0); 语句直接忽略了,没有执行,可能是什么原因啊?各位大虾,帮帮忙
发布网友
发布时间:2022-05-12 18:18
我来回答
共2个回答
热心网友
时间:2023-10-17 07:46
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#include <assert.h>
void assert( int expression );
assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,
然后通过调用 abort 来终止程序运行。
请看下面的程序清单badptr.c:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main( void )
{
FILE *fp;
fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert( fp ); //所以这里不会出错
fclose( fp );
fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败
assert( fp ); //所以这里出错
fclose( fp ); //程序永远都执行不到这里来
return 0;
}
[root@localhost error_process]# gcc badptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: Assertion `fp'' failed.
已放弃
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>
用法总结与注意事项:
1)在函数开始处检验传入参数的合法性
如:
int resetBufferSize(int nNewSize)
{
//功能:改变缓冲区大小,
//参数:nNewSize 缓冲区新长度
//返回值:缓冲区当前长度
//说明:保持原信息内容不变 nNewSize<=0表示清除缓冲区
assert(nNewSize >= 0);
assert(nNewSize <= MAX_BUFFER_SIZE);
...
}
2)每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败
不好: assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);
好: assert(nOffset >= 0);
assert(nOffset+nSize <= m_nInfomationSize);
3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题
错误: assert(i++ < 100)
这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。
正确: assert(i < 100)
i++;
4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感
5)有的地方,assert不能代替条件过滤
文章出处:http://www.diybl.com/course/3_program/c++/cppjs/20071111/85534.html
摘自《高质量C/C++编程指南》Page 41-42...
程序一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本发行给用户使用。
断言assert 是仅在Debug 版本起作用的宏,它用于检查“不应该”发生的情况。示例6-5 是一个内存复制函数。在运行过程中,如果assert 的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。
void *memcpy(void *pvTo, const void *pvFrom, size_t size)
{
assert((pvTo != NULL) && (pvFrom != NULL)); // 使用断言
byte *pbTo = (byte *) pvTo; // 防止改变pvTo 的地址
byte *pbFrom = (byte *) pvFrom; // 防止改变pvFrom 的地址
while(size -- > 0)
*pbTo ++ = *pbFrom ++ ;
return pvTo;
}
示例6-5 复制不重叠的内存块
assert 不是一个仓促拼凑起来的宏。为了不在程序的Debug 版本和Release 版本引起差别,assert 不应该产生任何副作用。所以assert 不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。如果程序在 assert 处终止了,并不是说含有该assert 的函数有错误,而是调用者出了差错,assert 可以帮助我们找到发生错误的原因。
很少有比跟踪到程序的断言,却不知道该断言的作用更让人沮丧的事了。你化了很多时间,不是为了排除错误,而只是为了弄清楚这个错误到底是什么。有的时候,程序员偶尔还会设计出有错误的断言。所以如果搞不清楚断言检查的是什么,就很难判断错误是出现在程序中,还是出现在断言中。幸运的是这个问题很好解决,只要加上清晰的注释即可。这本是显而易见的事情,可是很少有程序员这样做。这好比一个人在森林里,看到树上钉着一块“危险”的大牌子。但危险到底是什么?树要倒?有废井?有野兽?除非告诉人们“危险”是什么,否则这个警告牌难以起到积极有效的作用。难以理解的断言常常被程序员忽略,甚至被删除。
【规则6-5-1】使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。
【规则6-5-2】在函数的入口处,使用断言检查参数的有效性(合法性)。
【建议6-5-1】在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。
【建议6-5-2】一般教科书都鼓励程序员们进行防错设计,但要记住这种编程风格可能会隐瞒错误。当进行防错设计时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。
ASSERT宏中应该包含的元素:
判断条件;输出当前断言失败的位置(文件、行数等);返回错误;终止程序...
几种典型的ASSERT的写法:
VC中的写法:
#define ASSERT(f) \
do \
{ \
if (!(f) && AfxAssertFailedLine(THIS_FILE, __LINE__)) \
AfxDebugBreak(); \
} while (0) \
#define _ASSERT(expr) \
do { if (!(expr) && \
(1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, NULL))) \
_CrtDbgBreak(); } while (0)
其他平台的写法:
# define ASSERT(x) ((x) || (dbg_printf("assertion failed ("__FILE__":%d): \"%s\"\n",__LINE__,#x), break_point(), FALSE))
热心网友
时间:2023-10-17 07:46
凡是响应assert 说明异常
所以要做的 不是避免assert产生的闪退
而是根据每个闪退的点
避免出现assert失败的情况。
C++ assert(0); 语句直接忽略了,没有执行,可能是什么原因啊?各位大虾...
3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题 错误: assert(i++ < 100)这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。正确: assert(i < 100)i++;4)assert和后面的语句应空一行,以形成逻辑和...
...error是什么原因啊?各位大虾帮帮忙啊!!!我在线等,谢啦!!!
27 0x001B 磁碟机找不到要求的磁区。28 0x001C 印表机没有纸。29 0x001D 系统无法将资料写入指定的磁碟机。30 0x001E 系统无法读取指定的装置。31 0x001F 连接到系统的某个装置没有作用。32 0x0020 The process cannot access the file because it is being used by another process.33 0x002...
我幻想2总进不去怎么半(总是错误,无法执行,我下了补丁)各位大虾帮...
游戏有问题,需要重新下载;或者是电脑有问题,重装一次系统
JAVA.包 JAVA类 JAVA APPLET ...等跟JAVA挨得上边得都要!
17,什么时候用assert。 断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true。如果表达式计算为 false,那么系统会报告一个 Assertionerror。它用于调试目的:assert(a > 0); // throws an Assertionerror if a <= 0断言可以有两种形式:assert Expression1 ;assert Expression1 : Expression2 ; Ex...
电脑待机是灰色的,无法使用待机,怎么办,各位大虾帮忙指点指点了!在此谢...
(3)如果你在电脑进入待机状态过程中按了USB鼠标的按钮,很可能导致USB老鼠和USB键盘无法唤醒电脑的故障,目前没有好的办法解决,只能建议你通过按机箱开机按钮来唤醒电脑。(4)如果你使用的是Nero Burning Rom 5.0~5.5,操作系统为Windows XP SP1,在待机和休眠时会出现死机现象。建议升级Nero。我...
...打开文件却很慢,是什么原因啊?!!各位大虾,帮帮忙了!!!急!!!_百 ...
一般来说,由于USB接口速度较慢,因此相应设备会对电脑启动速度有较明显的影响,应该尽量在启动后再连接USB设备。如果没有USB设备,那么建议直接在BIOS设置中将USB功能关闭。 4、是否使用了磁盘压缩 因为“磁盘压缩”可能会使电脑性能急剧下降,造成系统速度的变慢。所以这时你应该检测一下是否使用了“磁盘压缩”,具体操作...
...成因是什么,以及它溢出的演示、怎样才能够防范它呢?请各位大虾...
造成缓冲区溢出的原因是程序中没有仔细检查用户输入的参数。例如下面程序: void function(char *str) { char buffer[16]; strcpy(buffer,str); } 上面的strcpy()将直接把str中的内容copy到buffer中。这样只要str的长度大于16,就会造成buffer的溢出,使程序运行出错。存在象strcpy这样的...
...压强都可也)不要太简单的,20道就好,请各位大虾速度啊!急!!!在线...
C.用量筒测量 溢出的水(或小烧杯中的水) 的体积V;D.计算小石头受到的浮力,F浮= ρ水gV 。(3)小刚完成该实验后从溢水杯中取出小石头直接放在已调好的天平上测出质量,求出了小石头的密度.你认为小刚这样做,测得的石头密度值与实际密度相比偏 大 (选填“大”或“小”)了,原因是 质量偏大(或体积偏小) ...
...0XE100CBA0,0X0C08204)是什么原因啊 求各位大虾
你好!Stop:0x00000019 (等同于新式蓝屏表示代码 BCCode: 19)0x00000019 磁盘驱动器在磁盘找不到指定的扇区或磁道.(xyz5819 意念时空)请使用系统自带的磁盘纠错功能检查各个分区有无磁盘错误.依然不行就使用DiskGenius>检测和修复硬盘坏道.(xyz5819 意念时空)更多帮助请LZ去微软帮助和支持>http://...
求魔兽rpg地图,各位大虾帮帮忙!好像是天地劫的那个版本,里面箭塔升级...
与之相反,当玩家骑在坐骑上时,所有的攻击和伤害都直接作用于玩家身上,而坐骑不会受到伤害。如果一个骑在上面的玩家死掉了,坐骑变为“未召唤”[Unsummon]状态,当玩家复活回到世界中,可以使用“再召唤”[Resummoning]来找回坐骑。购买乘骑需要一定的声望.在一些副本中也有可能掉落乘骑,这类乘骑可以直接使用,没有...