动态内存函数的介绍
使用malloc和free
void* malloc (size_t size);
函数说明:malloc函数向操作系统申请一块连续可用的内存,并返回指向这块内存的指针。
返回值:void*,因为malloc并不知道你的内存放入什么类型的数据。
参数:size表示内存的大小(字节)
注意:malloc函数的声明在stdlib.h 头文件中
void free (void* ptr);
说明:free函数是专门是用来做动态内存的释放和回收的。
返回值:void,无返回值。
参数:ptr表示这块动态内存的首地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <stdio.h> #include <stdlib.h> int main() { int *ptr = NULL; int size = 10; ptr = (int *)malloc(size * sizeof(int)); if(NULL == ptr) { printf("内存分配失败"); return 0; } for (int i = 0; i < size; i++) { *(ptr + i) = 0; } for (int i = 0; i < size; i++) { printf("%d ", *(ptr + i)); } free(ptr); ptr = NULL; return 0; }
|
使用calloc函数
void* calloc (size_t num,size_t size);
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h> #include <stdlib.h> int main() { int *ptr = (int *)calloc(10,sizeof(int)); if(NULL == ptr) { printf("内存分配失败"); return 0; } free(ptr); ptr = NULL; return 0; }
|
使用realloc函数
void* realloc (void* ptr, size_t size);
说明:为了合理的分配内存,我们一定会对内存的大小做灵活的调整。
返回值:为调整之后的内存起始位置,这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
参数:
ptr:表示是要调整的内存地址
size:表示调整之后新大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <stdio.h> #include <stdlib.h> int main() { int* ptr=(int *)calloc(1, sizeof(int)); if (NULL == ptr) { printf("分配内存失败"); return 1; } *ptr = 666; ptr = (int *)realloc(ptr, 2 * sizeof(int)); *(ptr + 1) = 888; for (int i = 0; i < 2; i++) { printf("%d ", ptr[i]); } free(ptr); ptr = NULL; return 0; }
|
注意事项:realloc在调整扩展内存空间时,存在两种情况
情况1:原有空间有足够的空间,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
情况2:原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。
常见的动态内存错误
(1)每次动态分配都要做检查
1 2 3 4
| if(ptr == NULL) { printf("内存分配失败"); }
|
(2)动态开辟空间的越界访问
1 2 3 4 5 6
| int i = 0 int *ptr = (int *)malloc(10*sizeof(int)); for(i = 0;i<= 10;i++) { *(ptr + i) = i; }
|
(3)非动态开辟内存使用free释放
1 2 3
| int a = 10; int *ptr = &a; free(ptr);
|
(4)使用free释放一块从非首地址开始的动态内存
1 2 3
| int *ptr = (int *)malloc(10*sizeof(int)); ptr++; free(ptr);
|
(5)对同一块动态内存多次释放
(6)动态开辟内存忘记释放(内存泄漏)
1 2 3 4 5 6 7 8 9 10
| void test() { int *ptr = (int *)malloc(10*sizeof(int)); if(ptr == NULL) { printf("内存分配失败"); } return; }
|
几个经典的笔试题
题一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <stdio.h> #include <stdlib.h> #include <string.h> void GetMemory(char *p) { p = (char *)malloc(100); return; } int main() { char *str = NULL; GetMemory(str); strcpy(str,"hello world"); printf(str); return 0; }
|
报错:编译正常,运行报错

题二
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdio.h> char *GetMemory() { char p[] = "hello world"; return p; } int main() { char *str = NULL; str = GetMemory(); printf(str); return 0; }
|
报错:编译错误

题三
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <stdio.h> #include <stdlib.h> #include <string.h> void GetMemory(char **p,int num) { p = (char *)malloc(num); return; } int main() { char *str = NULL; GetMemory(&str,100); strcpy(str,"ethaniel"); printf(str); return 0; }
|
报错:未报错,但是没释放动态内存
题四
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include<stdio.h> #include<string.h> int main() { char *str = (char *)malloc(100); strcpy(str,"ethaniel"); free(str); if(str !=NULL) { strcpy(str,"blog"); printf(str); } return 0; }
|
报错:释放后再次调用导致的报错
