C语言内存空间的要点包括:
-
掌握访问内存空间最核心即是指针。指针可以理解为内存类型资源的地址。
-
明白指针变量:存放指针这个概念的盒子。
-
C语言编译器对指针概念有两个疑问:
分配多大的空间:
在32位系统中,指针4个字节。
空间里存放的地址,所指向内存的读取方法是什么?
*前的数据类型决定读取的方法。
eg.char p指将p地址的值以char类型取出 -
指针指向内存空间,一定要保证合法性:
内存操作的大小
内存的变化性,可读可写 -
指针+修饰符:将指针的限制范围告知用户。
例如以下变量的定义
const char p :指针指向空间可变,空间内容不可修改。应该理解成const char型
char * const p:指针指向的空间不可变。多表示硬件资源定义。
const charconst p:指向不可变,内容不可变,多表示ROM。
volatile:防止优化指向内存地址。
typedef:为指针取更容易识别的别名。 -
指针+运算符:++、–、+、-
定义一个指针±1:指向指针下(上)一个单位(int、char…,大小可以使用sizeof(p)查看)的内存地址。
指针++、–:更新地址的值。
指针+[n]:指针标签访问方式。可以用于非线性访问(直接访问某地址),取出标签中的值。 -
指针的逻辑操作符:有意义的操作符包括:= =,! =
常用方法包括
1.跟一个特殊值进行比较,eg.0x0 地址无效值,可以按照结束处理if(p==0x0)
2.指针必须是同类型的比较才有意义。 -
多级指针:(**p)
C语言提供的地址的地址空间
将离散在计算机中的各种内容,通过指针放进线性连续的地址中,方便使用。
典型的代码有:
main(int argc,char *argv[ ])
1.argc为整数
2.argv为指针的指针(可理解为:char **argv 或者 char *argv[ ] 或者char argv[ ][ ] ,argv是一个指针数组)
注:main( )括号内是固定的写法。 -
数组的定义:
指针变量的特殊化,是对内存分配的一种形式。
定义一个确定大小的空间,以及读取方式。
数组的初始化:
数据类型 数组名 【空间大小】(作用域是在申请的时候)
空间赋值:按照标签逐一处理,a[ ]={ x,x,x,x,x};
CPU内部本身一般不支持空间到空间的拷贝,需要调用函数库来实现。
数组空间的初始化和变量的初始化本质不同,尤其是在嵌入式的开发中,空间的初始化往往需要库函数的辅助。
关于数组的存放
软件最小空间为char
存字符char buf【】={‘a’,‘b’,‘c’};
如果buf当成字符串来看,最后加上一个“\0”
存字符串 char buf【】={“abc”};
为数组第二次内存初始化赋值,需要对元素进行逐一处理。 -
字符拷贝函数strcpy、strncpy原则:
内存空间和内存空间的逐一赋值的功能的一个封装体。一旦空间中出现了0这个特殊值,函数结束。
strcpy存在严重内存泄漏函数,实际上在工程中不允许使用
拷贝三要素:1.什么数据,2.拷到哪里,3.拷贝个数 -
字符空间和非字符空间的区别:
字符空间:
通过ASCII编码来解码的空间—>>方便人查看的方式
用户可以通过printf·(“%s”)查看
字符空间以\0作为结束标志
非字符空间:
比如为数据采集得到的二进制序列,不存在正负号,专门开辟一个存储这些数据盒子。
所以非字符空间的结束标志并不是\0,而是用户操作限制的最后一位数。
非字符空间拷贝函数:memcpy()依然遵循拷贝三要素拷贝三要素:1.什么数据,2.拷到哪里,3.拷贝个数
常用——无符号类型unsigned char 表示数据——有符号类型signed char 表示数值 -
指针数组:数组中存放的是地址。
定义一个指针,指向首地址: -
结构体字节对齐:
分配固定的空间(4字节或8字节对齐)再将数据类型分别存入空间。会出现分配的空间在某些情况下空余(比如4字节对齐,依次定义了char、short、int型。前两个类型占据3字节,int占4字节装不下,空余1个字节)以这种牺牲空间方式换取时间的效率。
最终结构体的大小一定是分配字节对齐值的倍数。
创建结构体时,应当注意定义的顺序,以求优化结构体的占用空间。 -
内存分布:
内存包含两个属性:1. 内存空间大小 2.在哪里。
C语言编译器编译时,先对各文件进行汇编生成.o文件,再定义一个程序运行的空间,将汇编后的文件插入运行空间称为链接,插入的空间一般称为段空间。
栈空间:运行时,函数内部使用的变量,函数一旦返回释放,生存周期是在函数内。
堆空间:运行时,可以自由,自我管理的分配和释放的空间,生存周期是由程序员决定。
分配:malloc();一旦成功,返回分配好的地址,只需要接收即可。堆积新地址的读法,由程序员灵活把握输入参数指定分配的大小,单位是B。(比如,char p;p=(char)malloc(100);)
释放:free(p);
内存中空间的大致分布:
—————————————————————————————————————————————————————————0xffffffff |
---|
内核空间 (应用程序不能访问) |
———————————————————————————————————————————————————————————— |
栈空间(局部变量的空间) RW(可读可写) |
———————————————————————————————————————————————————————————— |
运行时的堆空间(malloc申请的空间) |
———————————————————————————————————————————————————————————— |
只读数据段 R(只读) |
———————————————————————————————————————————————————————————— |
全局数据空间 RW(可读可写) |
———————————————————————————————————————————————————————————— |
代码段(代码运行的空间) R(只读) |
————————————————————————————————————————————————————————————0x0 |
内存中存在只读空间,不能对其进行写入操作。
- linux操作系统包含工具
size命令
其调用结果是显示程序的使用空间大小信息
主要包含:text 代码段 data 数据段 bss 未初始化的数据段 dec 十进制大小 hex 十六进制大小 filename 文件名等信息
nm命令: 列出某些文件中的符号(说白了就是一些函数和全局变量等)。