学习内存管理和预处理,结构体时所遇到的问题。

1.数据存放区域?
.bss段:未初始化的全局变量。
.data段:初始化过的全局变量。
.rodata段:常量数据。
.text段:代码段。
栈(stack):临时变量,部分整数常量。
堆(heap):malloc,recalloc,free。由操作者自行分配。
2.野指针出现的原因?如何防止野指针?
野指针:未初始化,随机指向一块内存的指针。
如何避免野指针:养成以下几点良好的编码习惯
⑴当指针没有指向时,置为空。
⑵当对指针指向的内存空间进行赋值的时候,要为指针分配空间。
⑶malloc分配完时一定要检查malloc是否分配成功。
⑷要初始化空间(memset(ptr,’\0’,sizeof(char)*100))
⑸用完空间之后要释放空间(free(ptr))
⑹释放完之后要置为空。
3,出现段错误的原因?如何调试?
访问了错误的或者不存在的内存段。
⑴利用gdb逐步查找段错误。加上-g -rdynamic参数进行编译。
⑵分析core文件。gdb ./a.out core
⑶段错误时启动调试
⑷利用backtrace和objdump进行分析。(没有gdb调试工具)
4.指针和数组的比较?
数组保存在静态数据区或者栈上。地址不可变,内容可变。
指针可以指向任意类型的内存块。特征是可变。
不能直接对数组名进行比较,复制只能用strcpy函数。可以对指针直接进行比较。
指针的内存容量是定值,而数组内存容量不一定相同。
5.宏定义的编程要点:
⑴宏定义是宏替换,不能添加或删除符号或字符
⑵宏定义不是说明或语句,行末不必加分号
⑶必须在函数之外,作用域直到源程序结束。要终止需要加上“#undef”命令
⑷若用括号括起来,不用进行宏替换
⑸允许嵌套
⑹可以对输出格式作宏定义。
6.宏定义的使用技巧
⑴防止一个头文件被重复包含
⑵得到指定地址上的一个字节或字
⑶求最大值和最小值
⑷得到一个field在结构体(struct)中的偏移量
⑸得到一个结构体中field所占用的字节数
⑹按照LSB格式把两个字节转化为一个Word
⑺按照LSB格式把一个Word转化为两个字节
⑻得到一个变量的地址
⑼得到一个字 的高位和低位字节
⑽防止溢出的一个方法
⑾对于IO空间映射在存储空间的结构、输入输出处理
⑿使用一些宏跟踪调试
7.#和##的区别
#是对于它所引用的宏变量通过替换在其左右加上一个双引号。##是连接符,用来将两个Token连接为一个Token。
8.结构体的定义,与数组的区别?
struct 结构体名
{
类型名1,成员名1;
类型名2,成员名2;
类型名3,成员名3;
};
结构体和数组都由多个元素组成;
各个元素在内存中的存储空间是连续的;
数组中各个元素的数据类型相同,而结构体中的各个元素的数据类型可以不相同。
9.内存对齐正式原则
数据类型自身的对齐值:基本数据类型的自身对齐值,等于“sizeof(基本数据类型)”。
指定对齐值;
结构体或类的自身对齐值:其成员中自身对齐值最大的那个值;
数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。
10.#define和typedef的区别?
typedef只是为了增加可读性而为标识符另起的新名称。#define是宏替换。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值