前提条件:32位环境
1. 指针就是地址。指针++的长度等于该类型的长度?我一直以为指针就是占四个字节的,是的,只是在使用指针做++运算时,地址的值会增加当前指针所指向数据类型的长度。指针本身会占用内存中4个字符的地址(64位系统会分配8个字符),而这4个字符的长度里面又存了指针所指向数据的地址值,所以指针可以指向复杂的数据类型。指针不能直接给值,而要给一个有值的变量或对象,因为里面要存地址,不存具体的数据。
2.空指针的地址是0x00000000?大多数环境下是这样,特殊的硬件环境可能不是。NULL只是个宏定义,一般是0.但也会是(void *)0。所以字符串的结尾不能用NULL,可能会报警告。
3.用printf看到的地址是操作系统分配的虚拟内存地址,而不是真实的物理内存地址。这样可以防止一个程序可以修改其他程序占用的内存地址。而且测试发现,同一个控制台程序,启动2次,里面变量可以显示一样的地址,但一个程序对值的修改不影响另外一个程序中的值。说明操作系统对虚拟内存中地址一样的却映射了物理内存的不同地址。
4.内存碎片化。在c中使用malloc,realloc函数向操作系统申请内存。realloc(void *p, size_t)中会把原占有内存释放掉,重新申请一块,然后把p对应的值拷贝过来。如果p=NULL,则跟malloc等效。在不断发出申请、free的过程中,是否会有很多碎片?如果能看到malloc的源代码会发现,malloc会先向操作系统申请一个大块的内存空间,然后切割成多个小块,按申请的大小切给各个调用malloc的对象,如果释放了,相邻的空闲空间会合并成一块空间。在用free之前,malloc分配的地址总是变大的,在有过free之后,malloc后的地址也许就在已用的之间。它会在最小的地址(链表的头)开始往后找空闲的能切出要求大小的空间。如果该快大的内存空间不够了,会再向操作系统申请,把新的作为原链表的最后一个数据成员。
5.内存对齐。PC机都会采用4字节对齐方式。所以结构体
typedef struct {
int int1;
double double1;
char char1;
doubel double2;
} hugo;
的大小是24.如果按照结构体的顺序把数据写入文本,遇到按8位字节对齐读取的机器的时候,就会发生错误。同时,intel,amd处理器的芯片是采用小端,就是假如4个字节的数据0x12345678存的时候是78 56 34 12.