内存管理、结构体、预处理问题解答

本文详细介绍了程序中内存的分配与管理,包括不同内存段的作用与使用场景,如.rodata、.bss、.data和.text等,并探讨了野指针、内存错误等问题及其解决方案。此外还介绍了C语言中的预处理机制,包括宏定义、文件包含及条件编译等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、常量数据都是存放在rodata中的吗?

   不是。常量不一定就放在rodata里,有的立即数直接和指令编码在一起,存放在代码段(.text)中。

 

2、数据存放的位置:

   bss段用来存放那些没有初始化和初始化为0的全局变量;

   data段用来存放那些初始化为非零的全局变量;

   Rodata就是用来存放常量数据的;

   text段存放代码(如函数)和部分整数常量;

   栈用于存放临时变量和函数参数,作为一种数据结构,可以用来实现函数的调用

   堆是最灵活的一种内存,其生命周期完全由使用者控制。

 

3、内存分配方式:

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

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

3)从堆上分配,亦称动态内存分配。程序在运行时用mallocnew申请所需要的内存,程序员自己负责在何时用freedelete释放内存。

 

4、形成野指针的原因:

  两种。第一种:指针变量没有初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的默认值时随机的;第二种:指针pfree或者delete之后,没有置为NULL,让人 误以为p是个合法指针。

 

5、常见的内存错误及对策:

(1)内存分配未成功,却使用了它。解决方法:在使用内存之前检查指针是否为NULL。一般使用mallocnew申请内存,应该用“ifp==NULL)”或“ifp=NULL)”进行防错处理;

(2)内存虽然分配成功,但是尚未初始化就引用它。解决方法:无论使用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略;

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

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

 

6、段错误以及调试方法:

   原因:没有权限;根本就不存在对应的物理存在;

   调试方法:利用gdb逐步查找段错误;

             分析core文件;

             段错误时启动调试;

             利用backtraceobjdump进行分析。

 

 

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)*结构体指针变量).成员名,如:“(*psname”;

(4)结构体变量数组名.成员名,如:“stu[0].name”。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值