深入理解C指针学习笔记七之动态内存管理

只针对额强大很大成都上源于它能追踪动态分配的内存。通过指针来管理这部分内存是很多操作的基础,包括一些用来处理复杂数据结构的操作。要完全利用这些能力,需要理解C的动态内存管理怎么回事。
C程序在运行时环境中执行,这通常是有操作系统提供的环境,支持堆和栈以及其他的程序行为。

注意 C99引入了变长数组,即数组的大小不是在编译时确定而是在运行时确定。不过数组一旦创建出来其长度就不会改变了。

迷途指针是一个常见的问题,我们通过事例说明什么情况下会出现迷途指针并介绍解决迷途指针的方法。指针使用不当可能会早场很多不可预期的效果,可能会产生无效效果,损坏数据或者终止数据。

动态内存分配

内存分配方法

在C语言中动态内存分配的步骤:

  1. 用malloc类的函数分配内存
  2. 用这些内存支持应用程序
  3. 用free函数释放内存(释放结束最好将指针置为NULL)

事例程序:

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

上述程序的内存分配情况:
这里写图片描述

注意上述使用sizeof(int)指定malloc分配内存的大小可以提高程序的兼容性。因为不同平台上int所占的字节数不同

每次调用malloc,程序结束时必须调用对应的free函数,以防止内存泄露。一般对指针进行释放内存之后将其设置为NULL,防止程序再次对其进行访问出错。

注意给字符串进行分配内存的时候特别注意要多分配一个字节装结束符’\0’(C语言字符串的结尾默认以’\0’结尾).

//此处pc最多只能装长度为5的字符串
char* pc = (char*)malloc(6);
//此处打印的是指针pc在内存中的长度,与malloc多少字节无关,64机器此处结果为8
*pc = "12345";
printf("%zu\n", sizeof(pc));
//此时输出的是字符串的长度,结果为5
printf("%zu\n", strlen(pc));

内存泄露

如果不再使用已经分配的内存却没有将其释放就会发生内存泄露,导致内存泄露的情况有一下两种:

  • 丢失内存地址
  • 应该调用free函数却没有调用(隐式泄露)
    内存泄露的一个重要问题是无法回收内存并重复利用,堆管理器可用的内存将变少,如果内存不断的被分配丢失,那么当需要更多的内存而malloc有不能分配时可能会导致程序终止,极端的情况下会导致操作系统崩溃。

丢失地址

下面一种情况可以导致内存丢失,即一个指针被连续两次分配内存:
int * pi = (int*)malloc(sizeof(int));
*pi = 5
……
pi = (int*)malloc(sizeof(int));

下图说明了两次分配内存的情况,其中500处的内存发生丢失。
这里写图片描述

还有另一种情况会发生地址丢失:
char* name = (char*)malloc(strlen("abc") + 1);
strcpy(name, "abc");
while(*name != 0) {
	printf("%c", name);
	name++;
}

每次迭代name会增加1,最后name会指向字符串结尾的NUL,分配的起始地址就丢失了

隐式内存泄露

如果程序在应该释放内存而实际却没有释放,也会发生内存泄露,如果我们不再需要某个对象但仍然保存在堆上,就会发生隐式的内存泄露。这种隐式泄露的带来的主要问题是对象在使用的内存其实不需要了,应该归还给堆,最坏的情况时堆管理器无法按需分配内存,导致程序不得不终止。
另一种容易发生内存泄露的情况是struct中含有指向动态分配的内存的指针,那么在释放结构体之前一定要先释放这些指针

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值