【C⼀C++】如何判断指针式malloc⼀new分配出来的

2025-05-22 16:18:33
推荐回答(5个)
回答1:

巨简单,提供两个方法,自行按照运行效率选择。
第一个,数据量大的话效率比较低。malloc是你自己程序调用的,那你就把malloc出来的地址记录下来不就好了,只要判断是不是有该地址,就知道是不是malloc出来的了,这种方法效率比较低,每次判断都要遍历你的地址池。
第二个,效率很高。首先在main函数开头随便创建2个变量,用于获取堆区起始位置和增长方向。下面就很简单了,你程序里面所有的变量要不就是栈区的,要不就是堆区的,要不就是静态和常量,那么你知道了堆区大概范围,只要判断对象是不是在该范围内不就能逆向推理出是不是malloc出来的了吗

//GC堆空间大小,此处为4096B
const int HEAP_SIZE=0x1000;
//GC堆空间阈值,超过该阈值GC会开始运行
int HEAP_Threshold=STACK_SIZE*0.8;
//GC堆空间起始地址
int HEAP_START_ADDR;
//GC堆空间结束地址
int HEAP_END_ADDR;
//程序堆空间增长方向
int HEAP_DIRECTION;
//获取GC堆空间起始地址和结束地址
HEAP_START_ADDR=(int*)malloc(1);
int TEMP=(int*)malloc(1);
//获取堆增长方向
HEAP_DIRECTION=(TEMP-HEAP_START_ADDR)>0?1:-1;
HEAP_END_ADDR=HEAP_START_ADDR+(HEAP_SIZE-1)*HEAP_DIRECTION;
if(HEAP_DIRECTION<0){
HEAP_START_ADDR=HEAP_END_ADDR+HEAP_START_ADDR;
HEAP_END_ADDR=HEAP_START_ADDR-HEAP_END_ADDR;
HEAP_START_ADDR=HEAP_START_ADDR-HEAP_END_ADDR;
}
free((int*)HEAP_START_ADDR);
free((int*)TEMP);

回答2:

这没戏的, 有些C++里的new/delete就是调用malloc/free实现内存分配的, win上的实现多半是都用heapalloc实现,这些信息基本上该有的都有了。 当然这不代表这两组东西就一样了, 因为new/delete多了一个步骤就是调用构造/析构函数

这种问题一般就是尽量别用malloc。 如果你写了一些函数,里面某个分配了内存给外头, 为了防止别人不清楚你用的是malloc还是new, 你最好写一个对应的释放内存函数

回答3:

本身来说这个事情是不可能的
因为这个表是由编译器构造的
而且就在X86,ARM, SPARC,或者常用的What ever linux/unix, windows, symbianOS平台上来说 malloc 跟 new 之于内存没有根本的关系, 都是操作系统跟cpu的分页调度, 地址转换之间玩的小把戏.
=====================================================
回下楼主
可能这个还是你对程序的运行理解不够明确吧, 我们就拿Unix类跟Windows这两个使用最广泛的系统来做说明

无论是那个系统, 在调用malloc后最后都会转到系统调用, 换句话说都会转入内核态,

Windows下 malloc->heapalloc->ntvirtualalloc->通过ssdt一个跳转转到系统控制的内核态进行处理

unix类系统下 根据申请内存的大小是否满足内存的一个页 来分别调用不同的系统调用, 大多数被slab分配器处理

这个没有听说过也没有关系

不知道你注意没有 无论你的程序再怎么变态, 泄露的内存再多, 只要你的程序退出, 绝对不会影响到系统的内存控制

只要你注意到了这个细节,你就会发现, 这个表其实是不存在与你的程序之中的, 或者说, 不存在于你的进程空间之中,

X86下的32位系统为每个进程提供了独立的4G空间, 无论你申请也好, 释放也好, 都在这个4G的空间内, 那么就明显了, 这个4G的空间本身就有个表在维护, 但是他跟你的进程没有关系.

你想获得这个表, 那就要去访问内核态空间, 访问系统底部的控制, 但是这跟通用完全是矛盾的, 先不说硬件级别的, 单单是不同系统间的内存控制就不可能相同, 普适性无从谈起.
===================================================
另外 我仔细看了看k19862217的程序 这样不能解决问题
假设在类中虚拟空间分配了内存P
在外部有野指针W 其值正好等于P
那么对W的判断返回则是malloc分配的内存
不可行

如果想要自己维护这个表的话
维护的不仅仅是已经分配的内存表
还需要一张指针表, 记录所有的指针初始化信息
程序段不只是这么简单
在性能上 不被允许

回答4:

可以自己定义malloc和free,将原来的malloc和free屏蔽掉,然后定义个链表来管理内存空间,做了个简单的例子,你参考下
//MyMalloc.h
#ifndef _MYMALLOC_H_
#define _MYMALLOC_H_

typedef struct malloc_info{
void * address;
int size;
struct malloc_info * next;
}malloc_info;

//声明自定义malloc及free函数
extern void *MyMalloc(unsigned int uSize);
extern int MyFree(void *pPtr);
extern malloc_info * GetInfo(void *pPtr);

//重定义malloc及free
#define malloc(size) MyMalloc(size)
#define free(ptr) MyFree(ptr);

#endif

//MyMalloc.c
#include
#include

typedef struct malloc_info{
void * address;
int size;
struct malloc_info * next;
}malloc_info;

static malloc_info* base = NULL;
void * MyMalloc(unsigned int size) {
malloc_info * tmp = base;
if(!base) {
base = (malloc_info *)malloc(sizeof(malloc_info));
base->address = malloc(size);
if (!base->address)
return NULL;
base->size = size;
base->next = NULL;
return base->address;
} else {
while(tmp->next) {
tmp = tmp->next;
}
tmp->next = (malloc_info *)malloc(sizeof(malloc_info));
tmp->next->address = malloc(size);
if (!tmp->next->address)
return NULL;
tmp->next->size = size;
tmp->next->next = NULL;
return tmp->next->address;
}
return NULL;
}

int MyFree(void * address) {
malloc_info * tmp = base;
malloc_info * next;
if (base && base->address == address) {
base = base->next;
free(tmp->address);
free(tmp);
return 0;
}
while(tmp) {
next = tmp->next;
if (next) {
if (next->address == address) {
tmp->next = next->next;
free(next->address);
free(next);
return 0;
}
}
}
return 0;
}

malloc_info * GetInfo(void * address){
malloc_info * tmp = base;
while(tmp) {
if(tmp->address == address) {
return tmp;
}
}
return NULL;
}
//test.c
#include
#include
#include "MyMalloc.h"

int main()
{
char * arr;
malloc_info * tmp;
arr = (char *)malloc(100 * sizeof(int));
tmp = GetInfo((void *)arr);
if (tmp) {
printf("size is %d\n" ,tmp->size);
}
free(arr);
getchar();
}
补充一下,如果像你想要的那样想判断合法与非法,用GetInfo,如果返回为NULL代表非法,非NULL就反回了这块内存的信息,包括地址的大小,如果想要其他信息的话你修改下结构体就行了,然后链表处理的部分你在好好看看,我着急没太仔细想就写了

回答5:

int * p = (int*)malloc(4);//假设p=0x5201314
//嗯 p是malloc的
free(p);
//p还是0x5201314,判断是否为malloc的意义是?????/?