C内存和类型
测试源码
1 | void *vp = calloc(4,4); |
输出
1 | int array[0] => 0 |
分析
关于变量类型和内存。申请了4×4字节的内存,内存是与变量无关的,初始化时的内存值为。
1 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ················ │ |
16字节内存作为整型数组使用
执行到下边的代码之后的内存。
1 | int *int_arr = vp; |
memory:
1 | 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 │ ················ │ |
一个int
类型大小为4个字节,所以16字节可以转成大小为4的整型数组。
16字节内存作为字符串数组使用
执行到下面的代码,内存变化为
1 | char *char_arr = (char *)vp; |
memory:
1 | 65 66 67 68 69 6a 6b 6c 6d 6e 6f 00 │ abcdefghijklmno· │ |
一个char
类型占用1个字节,16个字节可以放16个字符。
16字节作为结构体变量使用
执行到下面的代码,
1 | memset(vp,0,16); |
memory:
1 | 0c 00 00 00 54 6f 6d 20 4a 65 72 72 79 00 00 00 │ ····Tom Jerry··· │ |
执行下面的代码
1 | struct person { |
输出
1 | person age:12, name : Tom Jerry |
16字节的内存被person结构体使用了。
结构体间强转
执行到以下代码
1 | memset(vp+4,0,12); |
memory:
1 | 0c 00 00 00 6d 61 6e 00 00 00 66 61 74 00 00 00 │ ····man···fat··· │ |
输出
1 | annimal type: 12, type_name: man, description: fat |
总结
对于申请的内存得到的内存是无类型的,谁都可以使用。变量类型的作用是用来确定内存的边界。int
类型大小为4个字节,所以会以4个字节为单位进行切割。char
类型大小为1个字节,以1个字节为单位对16字节的数据进行切割。person
结构体,切割成两个部分。前4个字节作为整型age
,后12字节作为char
数组name
。annimal
结构体,将16字节切割给 type
、type_name
, description
。
扩展-数组
多维静态数组
静态数组int map[2][3] = {{1,2,3},{4,5,6}};
在内存的布局如下,前4×6 = 24个字节分别对应map中的值。根据列的长度得出行的个数。列的大小为4×3 = 12,可以将24分成2个。
1 | 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 │ ················ │ |
静态数组:int map2[3][2] = {{1,2},{3,4},{5,6}};
内存布局如下。和上面的map
变量内存布局一致。不同的是解析方法。
1 | 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 │ ················ │ |
静态数组: int map3[3][2][2] = {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}};
内存布局如下,切割方法,最小单位为2×4字节。map3[0][0][0] => 1
。
1 | 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 │ ················ │ |
字符串数组:char names[3][16] = {"AAA","BBBB","CCCCCCCCCCCCCCC"};
。
1 | 41 41 41 00 00 00 00 00 00 00 00 00 00 00 00 00 │ AAA············· │ |
多维动态数组
二维字符串数组创建方法一:
代码如下,4个字符串指针,决定了字符串的个数,指针所指向的地址由自己定义。
1 | void *vp = malloc(16); |
内存:
1 | 41 41 41 00 42 42 42 00 43 43 43 00 44 44 44 00 │ AAA·BBB·CCC·DDD· │ |
输出:
1 | str_arr_ptr_0 => AAA |
二维字符串数组创建方法二:
1 | void *vp = malloc(16); |
说明
与第一种不同的是,每个指向字符串数组的指针都要自己去申请。但是,好处是动态的,大小可以自己决定。C指针编程实际上是对内存操作的编程。
栈大小
每个操作系统都会限制栈大小,总栈大小和每个函数栈大小都会有不同的限制。
8M的函数栈,其实可以通过操作系统变更的。