一、malloc
1.常用表达式:int *p = (int *)malloc(n*sizeof(int));
为20个char*分配内存 char **p = (char **)malloc(20*sizeof(char*));
2.malloc()内是所需申请的字节数,而malloc本身并不知道要申请什么类型的字节,malloc本身的类型:
void *malloc( size_t size );若要返回指针类型,要使用强制类型转换。
3.p一定是指向指针的开头,不能p++,不然指针的指向发生移动,free崩溃
4.malloc在堆里,堆的内存:1G左右
5.栈和堆的区别
栈:由系统自行管理
堆:程序自行管理
6.malloc申请内存,利用free释放,如果没有释放,则出现内存泄漏
7.出现内存泄漏,则可用内存越来越少,设备速度越来越慢
8.内存泄漏很难解决的两点原因
(1)程序退出,操作系统将程序消耗的内存全部回收
(2)关机。所有内存回到初始状态
9.安装vld小软件,引用#include<vld,h>检测内存泄漏
二、calloc
1.int *p = (int *)calloc(10,sizeof(int));
//10表示数组长度,sizeof(int)表示每个格子的大小,用的不多,实际上10*sizeof(int)就是malloc的表达,比malloc多了一步将数组初始化为0
三、realloc
1.realloc:扩容 malloc想扩容,则用realloc
int *q = (int *)malloc(20*sizeof(int)); //创建新家
for(i = 0;i<10;i++)
{
*q[i] = *p[i]; //搬家
}
free(p); //释放旧地址
p = q; //更新新地址
q = NULL; //浅拷贝发生错误,多个指针不能指向同一个内存,所以q = NULL
free(p); //若不加q=NULL,则free崩溃(重复释放)
{ free(q);
2.int *p = (int *)realloc(20*sizeof(int)); //新的大小 重新分配20个格子的内存
3.若int *p = (int *)realloc(5*sizeof(int)); //即缩小容量会怎样?
realloc可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。
4.(1)windows编译器:重新申请一块“地”
(2)gcc:补加一块“地”
四、free
1.free如何得到长度信息?
malloc分配了两个空间,一个是管理空间(记录了管理信息),一个是实际空间,管理信息由结构体保存,如下:
struct mem_control_block {
int is_available; //这是一个标记?
int size; //这是实际空间的大小
};
而在结构体里记录了malloc申请的实际空间的大小,free释放的是指针指向的内存大小,而不是指针,指针在程序结束时销毁,由于free释放了它指向的内存大小,所以它最后返回一堆垃圾,free的源代码:
void free(void *ptr)
{
struct mem_control_block *free;
free = ptr - sizeof(struct mem_control_block);
free->is_available = 1;
return;
}
函数第二句中free的值减去一个结构体大小,释放了实际空间,让指针指向管理空间,然后管理空间里的信息会告诉操作系统释放实际内存的大小等信息。
http://blog.csdn.net/r91987/article/details/6337032
2.free崩溃的原因?
(1)越界
(2)指针的指向发生移动
(3)重复释放
五、一些小知识
1.C语言中三大缺点
(1)内存泄漏
(2)内存越界
(3)数组太丑
其它变量的写法:int a = 0; char *p = &a; 都是先分配好内存空间,再命名,而int Arr[10]则是先命名,再分配内存空间。
比如int Arr[10];原本按照定义是这样写的int [10]Arr;又例如
typedef unsiged long long uint64;
typedef int * Pint;
typedef int Arr[10];
typedef int (*Pfun)();
2.int *p:不能用sizeof(p)/sizeof(p[0]);
//error 结果是1,并不是想要求得的P的长度,如果P是数组则可用该公式
六、malloc的程序:用筛选法找出素数
{
assert(p != NULL);
int i;
for(i=0;i<n;i++)
{
p[i] = 1; //默认为1,是素数记为1,不是素数记为0
}
p[0] = 0;
p[1] = 0;
{
for(int j=i+1;j<n;j++)
{
if(j%i == 0)
{
p[j] = 0;
}
}
}
{
if(p[i] == 1)
{
printf("%d\n",i);
}
}
free(p);
}
int main(void)
{
SiftPrime(20);
}