目录
之前学过的内存开辟方式有:
int val = 20; // 在栈空间上开辟4个字节char arr[10] = {0}; // 在栈空间上开辟10个字节的连续空间
C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下:
void free (void* ptr);
- int* p = (int* ) malloc(10*sizeof(int));
- //int* p = (int* ) malloc(INT_MAX);//开辟不成功的情况
- if(p == NULL)
- printf("%s\n", strerror(errno));//返回错误信息
- else
- {
- //正常使用空间
- int i = 0;
- for(i=0; i<10; i++)
- *(p+i) = 2*i;
- }
- //当申请空间不再使用时,就应该还给操作系统
- free(p);//释放内存空间;
- p = NULL;
- //malloc 和 free要成对使用;
void* calloc (size_t num, size_t size); // 开辟一块内存空间,并且把空间的每个字节初始化为0。
- int *p = (int*)calloc(10, sizeof(int));
- //int* p = (int* ) malloc(10*sizeof(int));//对比malloc的使用
- if(NULL != p)
- {
- //使用空间
- int i = 0;
- for(i=0; i<10; i++)
- printf("%d ", *(p+i));
- }
- free(p);
- p = NULL;
void* realloc (void* ptr, size_t size); // 对ptr地址重新开辟空间size个字节,并返回一个地址
- int *ptr = (int*)malloc(100);
- int * p = NULL;
- if(ptr == NULL)
- printf("%s", strerror(errno));
- else
- {
- ;//正常使用空间
- }
- //p = (int *)realloc(ptr, 101);//此时p和ptr相同
- p = (int *)realloc(ptr, 1000);//此时p与ptr不同,是一块新的地址;
- if(p != NULL)//防止新地址开辟失败,所以不能直接放到ptr中
- {
- ptr = p;//这块空间始终由ptr来维护
- }
-
- free(ptr);//使用结束后释放ptr
- //注意:这列的p是临时变量,不是动态空间,函数结束就自动释放了,所以不需要free
- ptr = NULL;
realloc也能直接开辟空间
int* p = (int* )realloc(NULL, 40);//等价于malloc(40);
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
- int i = 0;
- int *p = (int *)malloc(10*sizeof(int));
- if(NULL == p){
- exit(EXIT_FAILURE);
- }
- for(i=0; i<=10; i++){
- *(p+i) = i;//当i是10的时候越界访问
- }
- free(p);
int a = 10;
int *p = &a;
free(p);//ok?
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
int *p = (int *)malloc(100);
free(p);
//可以在这里加一个 p = NULL;
free(p);//重复释放
while(1)
{
int* p = (int*)malloc(1);
}//这里没有动态内存释放,这个程序就会造成一直内存泄漏;
- void GetMemory(char *p)
- {
- p = (char *)malloc(100);
- }
- void Test(void)
- {
- char *str = NULL;
- GetMemory(str);
- strcpy(str, "hello world");
- printf(str);
- }
- //以上代码存在两个问题
- //1.str传值时候,对p赋值不会改变str;
- //2.malloc开辟了空间,最后没有释放,造成内存泄漏;
- //改进方法一:采用传地址,输出型参数
- void GetMemory(char **p)
- {
- *p = (char *)malloc(100);
- }
- void Test(void)
- {
- char *str = NULL;
- GetMemory(&str);
- strcpy(str, "hello world");
- printf(str);
- free(str);
- str = NULL;
- }
- //改进方法二:函数返回
- char* GetMemory(char* p)
- {
- p = (char *)malloc(100);
- return p;//这里因为p是堆区开辟的数据,可以返回,后面可以用引用
- }
- void Test(void)
- {
- char *str = NULL;
- str = GetMemory(str);
- strcpy(str, "hello world");
- printf(str);
- free(str);
- str = NULL;
- }
- char *GetMemory(void)
- {
- char p[] = "hello world";
- return p;
- }
- void Test(void)
- {
- char *str = NULL;
- str = GetMemory();
- printf(str);//打印出来应该是随机值,p数组出函数就销毁了,只返回了一个地址;
- }
- void Test(void)
- {
- char *str = (char *) malloc(100);
- strcpy(str, "hello");
- free(str);//释放后并不会把str置为NULL;应该加上 str = NULL;
- if(str != NULL)
- {
- strcpy(str, "world");//已经释放后,就造成非法访问内存;
- printf(str);
- }
- }