如何在C++中检测一个指针是否指向堆内存?

abc880 2009-03-04 10:45:11
比如:
void fun(int* pInt)
{
//在这里能否检测pInt是否是通过new得到的
}

请大侠们指教。
...全文
405 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
kostion 2009-03-09
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ssm1984119 的回复:]
还有如此古怪的问题。
方法倒是有一个,重写new,在你重写的方法中记录所有new的内存。判断某个内存是否为堆,拿这个记录一一查询。
[/Quote]
:)
ForestDB 2009-03-09
  • 打赏
  • 举报
回复
一个不怎么好的方法,看指针地址,如果在堆中,应该是个特别的范围,不过没有移植性。
hityct1 2009-03-09
  • 打赏
  • 举报
回复
据我所知,至少c++不能区分指针指向的空间是由new还是new[]生成的。
很土 2009-03-09
  • 打赏
  • 举报
回复
没有任何意义,写代码关心指针是不是new真的很没必要,这是舍本逐末啊。
  • 打赏
  • 举报
回复
试下读取指针的值,堆跟栈的区间应该还有区别的吧.
shminow 2009-03-08
  • 打赏
  • 举报
回复

LZ的问题很。。。奇怪。

重载new很少见,不建议。。。

来帮忙LZ分析下,


//new运行时函数的调用过程

new->HeapAlloc->RtlAllocateHeap

/*UserMod->KernelMod */


可以先调用Createheap创建一个堆, WIN系统会从空表指针FreeList[0]开始分配,
LZ可以用OD之类的调试器去查看FreeList空表前8个字节的表头,分配完后表头的Flag为01,空闲时为00;
可以利用Flag或者前8个字节的表头特征来盘队是不是指向Heap!!!


arong1234 2009-03-06
  • 打赏
  • 举报
回复
人家问的就是你为什么需要“确认”这个
[Quote=引用 2 楼 abc880 的回复:]
比如这样的需求:在一个类中保存另一个类的指针。
class Array
{
void SetPtr(int index, SomeClass* ptr);
private:
SomeClass* m_pData;
};

我要确认SetPtr获得的指针ptr是指向堆内存。
[/Quote]
smaltdd 2009-03-06
  • 打赏
  • 举报
回复
系统的栈和堆的基地址是有严格划分的,,看看windows内存管理吧。。

这样可以找到解决办法。。
ssm1984119 2009-03-06
  • 打赏
  • 举报
回复
我有个朋友重写过new和delete,然后解决了软件中内存泄露的问题。
abc880 2009-03-05
  • 打赏
  • 举报
回复
比如这样的需求:在一个类中保存另一个类的指针。
class Array
{
void SetPtr(int index, SomeClass* ptr);
private:
SomeClass* m_pData;
};

我要确认SetPtr获得的指针ptr是指向堆内存。
lei_zhuyan 2009-03-05
  • 打赏
  • 举报
回复
你可以看看一个存放在堆中的变量的地址 与一个存放在栈中的变量的地址的区别。
貌似是相差4位吧。

上次写代码的时候偶然发现的。

不知道这是碰巧呢 还是真的是这样。
ice50303 2009-03-05
  • 打赏
  • 举报
回复
我看你的表达有点问题,我按我的理解给你个……算是思路吧


void fun(int* pInt)
{
//在这里能否检测pInt是否是通过new得到的=?=是否是想检测pInt是否为空呢?

assert(pInt); //需要包含头文件 include<assert.h> ; 只是做测试用的,实际运行时可删除

}
threeleafzerg007 2009-03-05
  • 打赏
  • 举报
回复
重载 全局域的 operator new? 貌似没人这么做过!
说的过头了,不过很少有人这样做,并且往往不是非常推荐!
threeleafzerg007 2009-03-05
  • 打赏
  • 举报
回复
在用户层 可移植的代码 来判断一个指针是否来自堆上 很难实现

还有如此古怪的问题。
方法倒是有一个,重写new,在你重写的方法中记录所有new的内存。判断某个内存是否为堆,拿这个记录一一查询。

这是一个方法,一般都是重载类的 static operator new 难道你为每个类都要重写一遍,以维护一份全局域的堆指针链表? 重载 全局域的 operator new? 貌似没人这么做过!

编译器层可以实现,因为它本就不可移植,看看 realloc 这个函数,跟踪一下,它会用个函数判断 第一个指针参数 是不是来自于堆,不过至于你能不能找得到,就是你的问题了。
糊涂岁月 2009-03-05
  • 打赏
  • 举报
回复
void fun(int* pInt)
{
int a;
if(pInt > &a)
{
//在栈中
}
else
{
//在堆中
}
}
具体要看系统堆栈生长方向了。
lingyin55 2009-03-05
  • 打赏
  • 举报
回复
3楼说的是操作符new重载,例子网上很多。
[Quote=引用 4 楼 jaycnvip 的回复:]
我记得new是操作符不是函数,所以对楼上说的重写new很感兴趣,楼上有没有源码示例,贴出来让后来人学习学习。
[/Quote]
jaycnvip 2009-03-05
  • 打赏
  • 举报
回复
我记得new是操作符不是函数,所以对楼上说的重写new很感兴趣,楼上有没有源码示例,贴出来让后来人学习学习。
ssm1984119 2009-03-05
  • 打赏
  • 举报
回复
还有如此古怪的问题。
方法倒是有一个,重写new,在你重写的方法中记录所有new的内存。判断某个内存是否为堆,拿这个记录一一查询。
hongzao 2009-03-04
  • 打赏
  • 举报
回复
你要检测这干吗? 有什么需求吗

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧