第六、七章问题汇总

1.内存分配方式有哪几种?

(1)从静态存储区域分配。内存在程序编译时就已经分配好了,这块内存在程序的整个运行期间都存在,如全局变量、static变量等。

(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数之行结束时这些存储单元自动被释放。栈内存分配运算使用内置于处理器的指令集,效率很高,但分配的内存容量有限。

(3)从堆上分配,亦称动态内存分配。程序在运行时用malloc或new申请所需要的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

2.什么是野指针?

野指针不是NULL指针,是指向“垃圾”内存的指针。一般不会错用NULL指针,因为用if语句很容易判断。但是野指针是很危险的,if语句对它不起作用。

3.野指针成因

(1)指针变量没有被初始化

(2)指针p被free或者delete之后,没有被置为NULL,让人误以为p是个合法的指针。

4.常见的内存错误和对策

(1)内存分配未成功,却使用了它。解决办法是,在使用内存之前检查指针是否为NULL。

(2)内存分配虽然成功,但是尚未初始化就引用它。

(3)内存分配成功并且已经初始化,但是操作越过了内存的边界。

(4)忘记了释放内存,造成内存泄漏。动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。

(5)释放了内存却继续使用它。

5.段错误的调试方法

(1)利用gdb逐步查找段错误

(2)分析core文件

(3)段错误时启动调试

(4)利用backtrace和objdump进行分析

6.带参宏定义与自定义函数区别

#define S(a,b) a*b
area=S(3,2)

int S(int a,int b)
{ int s;
  s=a*b;
  return(s);
}
这两个有什么区别

#define S(a,b) a*b
area=S(3,2)

尽量少使用宏定义。宏定义是把S(a,b)简单地替换成a*b
这样会产生问题,最典型的两种:

(1).缺括号,比如aera=S(x+y,x-y),会被替换成x+y*x-y

(2).自增运算符

定义宏

#define S(a) (a)*(a)

结果S(a++),变成(a++)*(a++)这个大家都知道,在不同编译环境下会有不同结果。

也就是说,宏只是编译前简单替换代码内容,而函数真正产生代码。

宏是编译期的,函数是运行期的;

宏不是实体,而函数是一个可寻址的实体;

宏只是编译期替换,在程序里每遇到S(a,b),就用a*b代替,a和b两个实体并没有由宏实际产生,而函数S会在栈中定义两个对象a和b。

宏没有生存期、作用域之类的概念,而函数就有。

函数在运行过程中会在栈中产生函数调用过程活动记录,而宏则没有。

7.头文件尖括号<>和双引号""有什么区别

使用尖括号表示在包含文件目录中去查找,而不在源文件目录下去查找;使用双引号则表示首先在当前的原文件目录中查找,再去包含目录中去查找。

8.文件包含命令还要说明

(1)包含命令中的文件名可以用双引号也可以用尖括号括起来。

(2)一个include命令只能指定一个被包含文件,若有多个文件要包含,则需要用多个include命令。

(3)文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。

9.常用宏定义

#define              定义一个预处理宏
#undef             取消宏的定义


#include            包含文件命令
#include_next   与#include相似, 但它有着特殊的用途


#if                      编译预处理中的条件命令, 相当于C语法中的if语句
#ifdef                判断某个宏是否被定义, 若已定义, 执行随后的语句
#ifndef             与#ifdef相反, 判断某个宏是否未被定义
#elif                  若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-if
#else                与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else
#endif              #if, #ifdef, #ifndef这些条件命令的结束标志.
defined          与#if, #elif配合使用, 判断某个宏是否被定义


#line                标志该语句所在的行号
#                      将宏参数替代为以参数值为内容的字符窜常量
##                   将两个相邻的标记(token)连接为一个单独的标记
#pragma       说明编译器信息


#warning       显示编译警告信息
#error          显示编译错误信息

10.结构体和联合体区别

(1)struct和union都是由多个不同的数据类型成员组成, 但在任何同一时刻, union中只存放了一个被选中的成员, 而struct的所有成员都存在。在struct中,各成员都占有自己的内存空间,它们是同时存在的。一个struct变量的总长度等于所有成员长度之和。在Union中,所有成员不能同时占用它的内存空间,它们不能同时存在。Union变量的长度等于最长的成员的长度。
(2)对于union的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于struct的不同成员赋值是互不影响的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值