
各操作,其内存分布细节如图所示。
1.声明变量的内存
C语言中声明变量时,如图中int x1=10,在内存开辟三块内存空间,前两个存储下一个空间的地址,第三个存储实际值。
2.动态分配内存操作
图中int* x2=(int*)malloc(4);//此处写成malloc(sizeof(int))更为标准,这里为了方便区分括号里的内容。
表示从堆(heap)中动态分配4个字节的内存,用来存放int类型。
注意:
malloc分配的内存是4字节,不是4个int大小,要想分配4个int值,写malloc(sizeof(int)*4)。
分配的内存是用来存储int类型的值,而不是用来存储int*类型的地址值,
而x2是用来存malloc分配好的这块内存的地址值的。
malloc的作用是使用一块连续的可以按需求调节大小的空间。
这个操作的作用,存储若干个int类型
与数组区别如图:

malloc要用free之类的操作手动释放内存,不然会内存泄漏,也就是这块内存一直在被占着,无法被系统回收利用。
之前我们声明变量int a=1;或者声明数组int arr[]...之类的都会自动释放。
3.指针与数组名
int* x3=&x1,
只在内存开辟一块区域存指针x3,存放x1的地址,也就是一般讲的指针指向x1
对于
int arr[5]={4,5,3,6,9};
int* x3=arr;//此处的arr代表arr数组第一个元素的地址,指针x3存放该地址。
但需注意x3[4],x3[3]这类操作是被允许的,
它们会取到arr[4]和arr[3]的值,看起来像是arr数组赋给了x3,
看起来与刚刚首元素地址的这种理解相悖啊?
其实本质上在执行x3[3]这种操作,
编译器会先取x3的值(x3里存的地址,即arr首元素地址),
加上3 * sizeof(int)字节的偏移量,解引用得到该地址的值。
调用数组名arr,一般都代表首元素地址(即&arr[0]);
除了sizeof(arr)和&arr这两种情况,
sizeof(arr)计算arr整个数组的大小,&arr是整个数组的地址(类型为int(*)[5])
4.int** x5=(int**)malloc(sizeof(int*)*3)
分配可以存3个int*类型大小的内存(在64bit的程序下,地址大小为64bit=8字节,8*3=24字节)
x5存储的是malloc返回的内存块的起始地址,这个内存块包含3个连续的int*指针位置

302

被折叠的 条评论
为什么被折叠?



