C语言获取动态内存使用情况的方法

文章介绍了动态内存分配的概念,强调了其在编程中的重要性和可能的问题,如内存泄漏和空间碎片。提供了一个名为valloc的工具,用于检查动态内存的使用情况。valloc通过宏定义替换标准的内存分配函数,帮助统计内存分配和释放的状态。文章提供了一个示例,展示了如何使用valloc来检测未释放的内存,从而辅助内存管理。

获取动态内存使用

说明

内存动态分配是指在程序运行过程中,根据程序的需要动态地分配内存空间,以便存储数据或创建对象。内存动态分配通常使用指针来实现,通过调用系统提供的内存分配函数(如malloc、calloc等)来申请内存空间,申请成功后,返回一个指向该内存空间的指针,进而在程序中使用该指针来访问分配的内存空间。

内存动态分配的优点是可以动态地分配内存空间,避免浪费,提高内存使用效率。同时,动态分配的内存空间也可以随着程序的需求进行动态的释放,避免内存泄漏和出错。但是,使用内存动态分配也存在一些缺点,如容易出现内存泄漏、空间碎片等问题,需要程序员具有一定的技巧和注意事项才能正确、高效地使用内存动态分配。

这里,介绍一种可以检查动态内存使用情况的小工具valloc,以便统计动态内存的使用情况,以及检查是否有空间碎片忘记释放。用其方法代替的内存分配方法,可以计算动态内存使用的情况。

源码

源文件valloc.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static int count = 0;
static int use = 0;

void* v_malloc(size_t size)
{
	void* p;
	p = malloc(size ? size + sizeof(int) : 0);
	if (!p) return NULL;
	count++;
	*(int*)p = size;
	use += size;
	return (void*)((char*)p + sizeof(int));
}

void* v_calloc(size_t num, size_t size)
{
	void* p;
	p = v_malloc(num * size);
	if (!p) return NULL;
	memset(p, 0, num * size);
	return p;
}

void v_free(void* block)
{
	void* p;
	if (!block) return;
	p = (void*)((char*)block - sizeof(int));
	use -= *(int*)p;
	count--;
	free(p);
}

void* v_realloc(void* block, size_t size)
{
	void* p;
	int s = 0;
	if (block)
	{
		block = (void*)((char*)block - sizeof(int));
		s = *(int*)block;
	}
	p = realloc(block, size ? size + sizeof(int) : 0);
	if (!p) return NULL;
	if (!block) count++;
	*(int*)p = size;
	use += (size - s);
	return (void*)((char*)p + sizeof(int));
}

int v_mcheck(int *_count, int *_use)
{
	if (_count) *_count = count;
	if (_use) *_use = use;

	// if (count || use)
	// {
	// 	printf("|||----------->>> area = %d, size = %d\r\n", count, use);
	// 	return 1;
	// }

	return 0;
}

头文件 valloc.h

/*********************************************************************************************************
 *  ------------------------------------------------------------------------------------------------------
 *  file description
 *  ------------------------------------------------------------------------------------------------------
 *         \file  valloc.h
 *         \unit  valloc
 *        \brief  Test how much space is allocated
 *       \author  Lamdonn
 *      \details  v1.0.0
 ********************************************************************************************************/
#ifndef __valloc_H
#define __valloc_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdlib.h>

void* v_malloc(size_t size);
void* v_calloc(size_t num, size_t size);
void v_free(void* block);
void* v_realloc(void* block, size_t size);
int v_mcheck(int *_count, int *_use);

#define malloc v_malloc
#define calloc v_calloc
#define free v_free
#define realloc v_realloc

#ifdef __cplusplus
}
#endif

#endif

原理

比如分配 num 大小的空间

| <— sizeof(int) —> | <------- num -------> |
| _________________ | ________________ |

  1. 调用原版malloc函数分配sizeof(int)+num大小的空间
  2. 前面sizeof(int)大小的空间作为int型记录该片空间的大小num
  3. 增加记录分配次数到模块静态变量count,增加记录分配空间大小到模块静态变use
  4. 返回原分配地址向后偏移sizeof(int)后的地址给用户作为新的分配地址

同样,在释放内存时候

  1. 先把释放的地址向前偏移sizeof(int)得到实际的分配地址
  2. 实际地址的前sizeof(int)空间记录了该片空间的大小,模块静态变量countuse相应缩减
  3. 调用原版free函数释放实际的分配地址

然后,调用int v_mcheck(int *_count, int *_use);方法获取模块静态变量countuse即可得知动态内存的使用情况了

在头文件中增加了以下的宏定义

#define malloc v_malloc
#define calloc v_calloc
#define free v_free
#define realloc v_realloc

在需要统计动态内存的源文件文件中,只需添加valloc头文件进来,原版的mallocfree等函数则会被同名宏定义替换成v_mallocv_free等带v_前缀的函数,而无需改动其他代码。

例子

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    malloc(12);

    return 0;
}

像上面这种情况,我们分配了内存,如果不释放代码一复杂就很难发现内存没有释放。
加入valloc工具

#include <stdio.h>
#include <stdlib.h>
#include "src/valloc.h"

int main(int argc, char *argv[])
{
    int area = 0, use = 0;

    malloc(12);

    v_mcheck(&area, &use);
    if (area || use)
	{
		printf("|||----------->>> area = %d, size = %d\r\n", area, use);
	}

    return 0;
}

添加valloc头文件,该头文件宏定义会覆盖替代mallocfree等函数,从而不用改动其他代码,然后在结束的地方调用v_mcheck方法检查动态内存使用情况。

结果,没有释放的内存就报出来了,有1片空间没释放用了12大小的内存。

|||----------->>> area = 1, size = 12

小结

在需要测量动态内存使用的文件中简单的包含头文件而无需改动其他代码,然后在需要测量内存使用的地方调用v_mcheck方法检查动态内存使用情况。不需检查动态内存后,把头文件包含移除了即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值