1、常量数据都是存放在rodata中的吗?
不是。常量不一定就放在rodata里,有的立即数直接和指令编码在一起,存放在代码段(.text)中。
2、数据存放的位置:
bss段用来存放那些没有初始化和初始化为0的全局变量;
data段用来存放那些初始化为非零的全局变量;
Rodata就是用来存放常量数据的;
text段存放代码(如函数)和部分整数常量;
栈用于存放临时变量和函数参数,作为一种数据结构,可以用来实现函数的调用
堆是最灵活的一种内存,其生命周期完全由使用者控制。
3、内存分配方式:
(1)从静态存储区域分配,内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量、static变量等;
(2)在栈上创建,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算使用内置于处理器的指令集,效率很高,但分配的内存容量有限;
(3)从堆上分配,亦称动态内存分配。程序在运行时用malloc或new申请所需要的内存,程序员自己负责在何时用free或delete释放内存。
4、形成野指针的原因:
两种。第一种:指针变量没有初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的默认值时随机的;第二种:指针p被free或者delete之后,没有置为NULL,让人 误以为p是个合法指针。
5、常见的内存错误及对策:
(1)内存分配未成功,却使用了它。解决方法:在使用内存之前检查指针是否为NULL。一般使用malloc或new申请内存,应该用“if(p==NULL)”或“if(p!=NULL)”进行防错处理;
(2)内存虽然分配成功,但是尚未初始化就引用它。解决方法:无论使用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略;
(3)内存分配成功并且初始化,但操作越过了内存的边界。
(4)忘记释放内存,造成内存泄漏。动态内存的申请和释放,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。
6、段错误以及调试方法:
原因:没有权限;根本就不存在对应的物理存在;
调试方法:利用gdb逐步查找段错误;
分析core文件;
段错误时启动调试;
利用backtrace和objdump进行分析。
7、宏定义:#define
宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的。
无参宏定义形式:
#define 标识符 字符串
带参宏定义
#define 宏名(形参表) 字符串
8、文件包含的双引号和尖括号的区别:
使用尖括号表示在包含文件目录中查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找;使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中查找。
9、条件编译的三种形式:
第一种形式:#define 标识符
程序段1
#else
程序段2
#endif
第二种形式:#ifndef 标识符
程序段1
#else
程序段2
#endif
第三种形式:#if 常量表达式
程序段1
#else
程序段2
#endif
10、引用结构体变量中的成员:
(1)结构体变量名.成员名,如:“stu1.name”;
(2)结构体指针变量名->成员名,如:“ps->name”;
(3)(*结构体指针变量).成员名,如:“(*ps)name”;
(4)结构体变量数组名.成员名,如:“stu[0].name”。