天天看点

C指针之二:c的动态内存管理

参考书籍《深入理解c指针》原书作者:RichardReese华盛顿州塔尔顿州立大学副教授

篇首语

指针为什么强大?

因为能够追踪动态分配的内存,通过指针来管理这部分内存是很多操作的基础

由于可以先分配内存然后释放,因而应用程序可以更灵活高效的管理内存,不必为了适应数据结构可能的

最大长度而分配内存,只要分配实际需要的内存即可

一、动态内存分配

(一)、在c中动态分配内存的基本步骤

(1)用malloc 类的函数分配内存

(2)用这些内存支持应用程序

(3)用free函数释放内存(个人认为代码安全性,释放之后最好置为NULL)

int *pi = (int*)malloc(sizeof(int));
*pi = 5;
printf("*pi = %d\n",*pi);
free(pi);

注意下写法:
Demo1

int *pi;
*pi = (int*)malloc(sizeof(int)); // 内存地址赋值给变量值,不对

Demo2

pi = (int*)malloc(sizeof(int)); // 正确,地址指向内存 

注意内存访问越界的问题,错误示例
char *pc = (char*)malloc(6);
for(int i = 0;i<8;i++)
{
    *pi[i] = 0; 
}

(二)、内存泄漏
如果不再使用已经分配的内存却没有将其释放,就会发生内存泄漏
引发这种状况的原因如下:
(1)、丢失内存地址
(2)、应该调用free函数却没有调用
(3)、while循环申请内存
    char* chunk;
    while(1)
    {
        chunk = (char*)malloc(10000);
        printf("Allocating\n");
    }
    
1、丢失地址
    (1)、pi指针先后指向两块内存
    int *pi = (int*) malloc(sizeof(int));
    
    *pi = 5;
    pi = (int*)malloc(sizeof(int));
    这样一来,第一块内存就没有被释放
    
    (2)、直至遍历到字符串结尾
    char *name = (char*)malloc(strlen("Susan")+1);
    strcpy(name,"Susan");
    
    while(NULL!=*name)
    {
        printf("%c",*name);
        name++;
    }
    
2、隐式内存泄漏 
   没有用free释放      

二、动态内存分配函数

malloc 从堆上分配内存

realloc 在之前分配的内存块的基础上,将内存重新分配为更大或者更小的部分

calloc 从堆上分配内存并清零

free 奖励

int *pi = (int *)malloc(sizeof(int));
 free(pi);
 *pi = 10;
 2、多个指针指向同一块内存区域,然后通过一个指针释放那块内存区域
 int *p1 = (int *)malloc(sizeof(int));
 int p2 = p1;
 free(p1);
 3、使用块语句的时候,可能会出现一些问题
 int pi
 {
 int tmp = 5;
 pi = &tmp;
 }
 // 这里pi变成迷途指针      

继续阅读