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

获取动态内存使用

说明

内存动态分配是指在程序运行过程中,根据程序的需要动态地分配内存空间,以便存储数据或创建对象。内存动态分配通常使用指针来实现,通过调用系统提供的内存分配函数(如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方法检查动态内存使用情况。不需检查动态内存后,把头文件包含移除了即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux系统中,我们可以使用proc文件系统来获取运行中的进程的内存使用情况。我们可以通过读取/proc/[PID]/status文件来获取进程的内存信息。下面是一段示例代码,用于获取指定进程的内存运行情况: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUF_SIZE 1024 int main(int argc, char *argv[]) { if (argc != 2) { printf("用法:./meminfo <进程ID>\n"); return 1; } // 构造/proc/[PID]/status文件路径 char path[BUF_SIZE]; snprintf(path, BUF_SIZE, "/proc/%s/status", argv[1]); // 打开文件并读取内容 FILE *fp = fopen(path, "r"); if (fp == NULL) { printf("打开文件失败!\n"); return 1; } char line[BUF_SIZE]; char *name, *value; int mem_size = 0; while (fgets(line, BUF_SIZE, fp)) { // 提取内存信息 name = strtok(line, ":"); value = strtok(NULL, " kB\n"); if (strcmp(name, "VmRSS") == 0) { mem_size = atoi(value); break; } } fclose(fp); // 输出内存使用情况 printf("进程 %s 的内存使用情况为 %d kB\n", argv[1], mem_size); return 0; } ``` 在上述代码中,我们首先通过命令行参数获取了指定进程的PID,然后构造了/proc/[PID]/status文件的路径。接着,我们打开文件并逐行读取文件内容,使用strtok函数提取了内存信息。在这里,我们只获取了进程的“VmRSS”字段,即进程实际使用的物理内存大小。最后,我们输出了进程的内存使用情况。 注意,/proc/[PID]/status文件中包含了很多其他信息,可以根据需求添加代码来获取其他信息。同时,也可以使用其他工具(如top、ps等)来获取进程的内存使用情况

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值