首页 > 系统相关 >C指针之二:c的动态内存管理

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

时间:2022-11-07 19:32:17浏览次数:40  
标签:malloc int free 之二 内存 动态内存 pi 指针


参考书籍《深入理解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 奖励

三、用free函数释放内存
1、指针在释放之后仍然可能有值,这样的指针称之为迷途指针
2、如果free的指针所指向的内存不是由于malloc分配的,那么用free释放不合法
如果free的指针所指向的内存不是由于malloc分配的,那么用free释放不合法
int num;
int pi = #
free(pi); // 未定义行为
3、将指针释放后置为NULL,防止产生迷途指针,什么是迷途指针呢?不为NULL的指针,
也不是指向常量的指针,而是指向“垃圾”内存的指针
4、重复释放同一块内存,程序会异常
int
p1 = (int*)malloc(sizeof(int));
int* p2 = p1;
free(p1);
free(p2);
5、堆和系统内存
6、程序结束前释放内存
四、迷途指针
一、几个示例
1、内存释放后,继续向这个位置写入数据,这样做的结果是不可预期的

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变成迷途指针


二、处理迷途指针
1、释放指针后置为NULL(最为常见)
2、写一个特殊函数代替free函数
3、用第三方工具检测迷途指针或者其他问题


标签:malloc,int,free,之二,内存,动态内存,pi,指针
From: https://blog.51cto.com/u_11320078/5831086

相关文章

  • C指针之一:指针和内存
    参考书籍《深入理解c指针》原书作者:RichardReese华盛顿州塔尔顿州立大学副教授如果想在C/C++道路上走的更远,那么必须非常熟悉指针1、关于指针大小的谣言,指针到底多大?指......
  • C++ 悬垂指针
    /***********************************************************************//一、迷途指针(悬垂指针)在计算机编程领域中,迷途指针与野指针指的是不指向任何合法的对象的......
  • 初识指针——取地址操作符
    1.int*p表示p是一个变量,指针变量。而*p是解引用操作符,或者叫间接访问操作符。32位的操作系统输出字符类型的大小是4个字节   64位的操作系统输出字符类型的......
  • 基础算法篇——双指针算法
    基础算法篇——双指针算法本次我们介绍基础算法中的双指针算法,我们会从下面几个角度来介绍:双指针简介双指针基本使用最长连续不重复字符列数组元素的目标和判断子序......
  • C语言初级阶段7——指针1
    C语言初级阶段7——指针1地址与指针1.地址:数据在内存中的存储位置编号,是一个常量。2.指针:指针的本质就是地址。指针变量的定义和声明1.指针变量:存储的数据是地址。2.......
  • C语言初级阶段7——指针2——特殊指针
    C语言初级阶段7——指针2——特殊指针指针函数:是一个函数,返回值类型是一个指针。#include<stdio.h>int*fun(){ //a是一个局部变量 inta=10; return&a;}intm......
  • C语言初级阶段7——指针3
    C语言初级阶段7——指针3指针数组:描述的是一个数组,存储的是指针#include<stdio.h>voidfun(int(*arr)[2]){ for(inti=0;i<2;i++) { for(intj=0;j<2......
  • leveldb学习笔记之二——源码目录结构
    说明从今天开始,将正式进入leveldb源码的学习。leveldb主要采用c++实现,整体代码比较规范,除了学习存储相关的原理,还可以学习c++相关的知识,提升c++的技巧。目录leveldb的目录结......
  • 实验4 类与数组、指针
    task5.cpp#include<iostream>#include"vectorInt.hpp"voidtest(){usingnamespacestd;intn;cin>>n;vectorIntx1(n);for(autoi......
  • <一>类,对象,this指针
    C++类:实体的抽象类型实体(属性,行为)->ADT(abstractdatatype)类(属性->成员变量,行为->成员方法)OOP语言4大特征抽象封装/隐藏(通过publicprivateprotected)......