题1.关于ASSERT:
题目描述
void func() { char b[2]={0}; strcpy(b,"aaaa"); }
以下说法那个正确()
A. Debug版崩溃,Release版正常
B. Debug版正常,Release版崩溃
C. Debug版崩溃,Release版崩溃
D. Debug版正常,Release版正常
题库答案:A
牛客网解析:
assert 含义是断言,它是标准C++的cassert头文件中定义的一个宏,用来判断一个条件表达式的值是否为ture,如果不为true, 程序会终止,并且报告出错误,这样就很容易将错误定位
通常我们开发的程序有2种模式:Debug模式和Release模式
- 在Debug模式下,编译器会记录很多调试信息,也可以加入很多测试代码,比如加入断言assert, 方便我们程序员测试,以及出现bug时的分析解决
- Release模式下,就没有上述那些调试信息,而且编译器也会自动优化一些代码,这样生成的程序性能是最优的,但是如果出现问题,就不方便分析测试了
因为在Debug中有ASSERT断言保护,所以要崩溃,而在Release优化中就会删掉ASSERT,所以会出现正常运行。
但是不推荐如此做,因为这样会覆盖不属于自己的内存,这是搭上了程序崩溃的列车,即未定义行为,出现什么后果都有可能的,程序员的职责是保证不越界,而不是追问越界之后会发生什么。就像生活中违法不一定立刻被抓,但是迟早是要被抓的。
动手测试:
环境:Visual Studio 2017
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func()
{
char b[2] = { 0 };
strcpy(b, "aaaa");
}
int main()
{
func();
system("pause");
return 0;
}
测试结果:
-
debug版本
-
使用release版本:
先将运行库从MDd变成MD,配置从debug改成release,然后运行代码:
现象:release版本没有报错,不过窗口显示几秒钟后自动退出了!!!
-
使用了gcc 7.4.0编译器后
分别测试开调试和开优化,运行的时候:开调试会知道栈有出现问题,开优化直接知道溢出。编译的时候都会提示操作越界,而且数值精确(感谢唐同学热心解答!)
这道题的答案可能跟编译器选择有关系。在gcc 7.4.0中测试,两种配置都会报错。
题2. 编译内存:
题目描述
关于下面程序说法正确的是( )
class Item { private: char *desc; int storage; public: Item() { desc = new char[51]; } void setInfo(char *dsrc, int num) { strcpy(desc,dsrc); storage = num; } }; int main() { Item stock; stock.setInfo("pen",20); return 0; }
正确答案: A
你的答案: C (错误)
A. main函数定义了一个stock对象占8个字节
B. storage和desc成员各占4个字节
C. 存在内存泄漏的问题
D. 存在编译错误