判断一个地址是否位于堆中

renzhewh 2010-08-06 06:19:50

问题、判断一个地址是否位于堆中(C实现)
//《摘自More Effective C++》Item 27
// 解决方案基于这样一个事实:程序的地址空间被做为线性地址管理,程序的栈从地
// 址空间的顶部向下扩展,堆则从底部向上扩展。
//
// 在IsOnHeap函数中onTheSatck是一个局部变量,因此它在堆栈上。当调用IsOnHeap时,
// 它的栈框架(也就是它的activation record)被放在程序栈的顶端,因为栈在结构上是向下
// 扩展的(趋向低地址),onTheStack的地址肯定比任何栈中的变量或对象的地址小。
// 如果参数address的地址小于onTheStack的地址,它就不会在栈上,而是肯定在堆上。
// 在这里不考虑静态变量或其他类型变量

#include <stdio.h>
#include <malloc.h>

int IsOnHeap(const void* address)
{
char onTheStack;

printf("%x %x\n", address, &onTheStack);
return address < &onTheStack;
}

int main()
{
int* pp = (int *) malloc(sizeof(int));
printf("%d\n", IsOnHeap(pp));

int i, ii;
printf("%x %x\n", &i, &ii);

free(pp);
return 0;
}
// 在VS2008下编译,结果是
// 393720 12fe67 0 12ff54 12ff48
// 1、结果显示pp不在堆中,这与预想不同,为什么?
// 2、i 与 ii 的存储位置为何相差12个字节?(结构成员对齐为4字节,Debug模式)
...全文
551 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
asd03055102 2010-10-18
  • 打赏
  • 举报
回复
好hack的技术啊
renzhewh 2010-09-11
  • 打赏
  • 举报
回复
[code=c/c++]int main[/code]
zrebecca 2010-08-12
  • 打赏
  • 举报
回复
楼主说的是对的
yiruirui0507 2010-08-11
  • 打赏
  • 举报
回复
哦,一大早起来,搞糊涂了,楼主说的是对的!第一个问题能不能实现不确定.

第2个问题:i 与 ii 的存储位置为何相差12个字节?(结构成员对齐为4字节,Debug模式)

我用VC 6.0进行测试,就是相差4个字节. 12ff78 12ff74
yiruirui0507 2010-08-11
  • 打赏
  • 举报
回复
include <stdio.h>
#include <malloc.h>

int IsOnHeap(const void* address)
{
char onTheStack;

printf("%x %x\n", address, &onTheStack);
return address < &onTheStack;
}

int main()
{
int* pp = (int *) malloc(sizeof(int));
printf("%d\n", IsOnHeap(pp));

int i, ii;
printf("%x %x\n", &i, &ii);

free(pp);
return 0;
}
// 在VS2008下编译,结果是
// 393720 12fe67 0 12ff54 12ff48
// 1、结果显示pp不在堆中,这与预想不同,为什么?

如果参数address的地址小于onTheStack的地址,它就不会在栈上,而是肯定在堆上。
return address < &onTheStack; 应该是返回地址大小比较的值吧?小于,所以在堆上啊.有问题吗?哪里?
renzhewh 2010-08-11
  • 打赏
  • 举报
回复
duke56 那是小于运算符 好不好 哎
2010-08-10
  • 打赏
  • 举报
回复
楼主把静态数据区也当作堆?
duke56 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 renzhewh 的回复:]
引用 3 楼 duke56 的回复:
C/C++ code
address < &amp;onTheStack;//不知道你这个位移干吗用的?

在堆上分配的空间大多是高地址的,如12FF14等等,你这样一移,不管多大的数也给移成0,高位溢出丢掉,后边补0


这是位移吗????

还有这里只考虑栈与堆中的变量,不考虑其他,讨论在这个前提下,是否可以解决?
[/Quote]

比如一相int(一般为32位),你把一个int型的,不过int型的有数据有多少,移动32后,就等于是清0

一个内存的地址都是比较大的数值,让你这样一移,你说会留什么数据给你的?
renzhewh 2010-08-10
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 wjb_yd 的回复:]
楼主不要忘了,你的IsOnHeap函数上面还有main函数的堆栈,main函数上面还有crt库函数的堆栈,你这样判断肯定是错误的。

crt_startup |
\\\\ |
main |
\\\\      | 
IsOnHeap  |
[/Quote]

请你仔细看下我代码上的注释
因为栈在结构上是向下扩展的(趋向低地址),
onTheStack的地址肯定比任何栈中的变量或对象的地址小。
sacciness 2010-08-09
  • 打赏
  • 举报
回复
楼主的代码我在linux下用gcc试过了,结果正确啊,输出1
wjb_yd 2010-08-09
  • 打赏
  • 举报
回复
楼主可以先去看看线程堆栈模型,再来理解这个问题
wjb_yd 2010-08-09
  • 打赏
  • 举报
回复
楼主不要忘了,你的IsOnHeap函数上面还有main函数的堆栈,main函数上面还有crt库函数的堆栈,你这样判断肯定是错误的。

crt_startup |
\\\\ |
main |
\\\\      | 
IsOnHeap  |
jwpl190 2010-08-08
  • 打赏
  • 举报
回复
这个说起来就话就长了。
在我这输出
// 003836f8 0012fe67 0 0012ff54 0012ff48
看我用windbg说明一下:
0:001> !address 003836f8
00380000 : 00380000 - 00009000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsageHeap
Handle 00380000
是在Heap空间。
0:000> !teb
TEB at 7ffdd000
ExceptionList: 0012fd0c
StackBase: 00130000
StackLimit: 0012e000

“如果参数address的地址小于onTheStack的地址,它就不会在栈上,而是肯定在堆上。”
这句话不正确,stack是有大小限制的。要不怎么会有stack溢出错误呢。
003836f8 不在[0012e000,00130000]区间内,所以只能说不在当前线程的stack里面,别的
什么都说明不了。
另外,stack大小是可以在编译的时候设置的。
r11222 2010-08-08
  • 打赏
  • 举报
回复
上图只是告诉LZ哪一方是高地址哪一方是低地址, 不是说栈就在0000000,堆就在FFFFFFFF
r11222 2010-08-08
  • 打赏
  • 举报
回复
低地址 栈 0x00000000
.
.
.
.
.
.
.
.
高地址 堆 0xFFFFFFFF

大概示意图
r11222 2010-08-08
  • 打赏
  • 举报
回复
堆明显在栈的下方 ,也就是高地址端,为什么"如果参数address的地址小于onTheStack的地址,它就不会在栈上,而是肯定在堆上。

真是不解。。。。

另外。栈是从低地址向高地址增长的。。。。"
多喝水ooo 2010-08-07
  • 打赏
  • 举报
回复
我怎么记得堆也是从高地址开始,向低地址分配的。。。
失落的凡凡 2010-08-07
  • 打赏
  • 举报
回复
我觉得除非操作系统提供了相应的接口,用其它方法实现得到的结果都是不可信赖的。
renzhewh 2010-08-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 duke56 的回复:]
C/C++ code
address < &onTheStack;//不知道你这个位移干吗用的?

在堆上分配的空间大多是高地址的,如12FF14等等,你这样一移,不管多大的数也给移成0,高位溢出丢掉,后边补0
[/Quote]

这是位移吗????

还有这里只考虑栈与堆中的变量,不考虑其他,讨论在这个前提下,是否可以解决?
fengzhh 2010-08-07
  • 打赏
  • 举报
回复
linux,windows不同操纵系统加载应用程序时,内存分配方法不一样的。上述方法只适合x86 linux
加载更多回复(8)

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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