C++一个指针,我怎么知道传进来的地址是在堆上还是在栈上?

2022-10-06 22:44:12 +08:00
 kerrspace

假设我这个指针在 class 里面,从外面传进来的数据它既有可能是一个定义在栈区的 object ,又有可能是 new 在堆区上的

譬如我有一个 computer class ,然后 computer::computer(cpu*, gpu*, memory*) 在 int main 里面,我既可以 cpu c; gpu g; meory m; 然后 computer(&c, &g, &m)

也可以 computer(new cpu, new gpu, new memory)

那我在 class 里面怎么优雅地判断是哪一种情况?(要不要析构的时候销毁这三个 new ?)

BTW 。。我知道最简单的方法肯定是你就不要这么写

2876 次点击
所在节点    程序员
22 条回复
lmshl
2022-10-06 22:48:27 +08:00
按 c++ move 写不就行了?
lmshl
2022-10-06 22:49:34 +08:00
不使用 move 的话,比较简单的原则是谁创建谁销毁
yanqiyu
2022-10-06 22:55:49 +08:00
真的写出这种代码的话给调用者带来的迷惑不是一点半点...
堆栈生长方向不一样,你随便把这个指针和局部变量比大小就行,毕竟是 caller 传给你的
但是不要这么做,最好要么始终不转移所有权,要么始终转移所有权,要么用智能指针
gulu
2022-10-06 22:57:09 +08:00
gulu
2022-10-06 23:01:31 +08:00
判断一个内存段是否属于 heap ,需要借用 mm_struct 里面的 start_brk(heap 内存段的开始位置) 和 brk(heap 内存段的结束位置)。vma 的开始和结束地址在 mm_struct 的 start_brk 和 brk 之间,则说明地址在 heap 内存中。
leimao
2022-10-06 23:09:08 +08:00
> 那我在 class 里面怎么优雅地判断是哪一种情况?(要不要析构的时候销毁这三个 new ?)
最好不要这么干,object 不 own 那些 memory ,就别去干 delete 的事。
heiher
2022-10-06 23:15:20 +08:00
c++不用自动内存管理,就要显式约定 ownership ,不需要判断
BrettD
2022-10-06 23:16:27 +08:00
你这样写还这样问就说明没有把所有权归属问题想清楚
leonshaw
2022-10-06 23:16:40 +08:00
你也知道不要这么写,所有权也是函数 contract 的一部分。并且完全可以分配一块堆内存作为线程的栈(默认情况也是和堆类似分配方式)。
shawnsh
2022-10-06 23:19:46 +08:00
谁创建的指针,谁知道是用的哪个区,让他管回收,你只是使用,你不要管回收。如果要回收,那么就需要知道该指针的类型,是哪个区的。所以你要封装个对象,里面要有一个指针,还要有指针所在的区域,还要有是否调用者可以释放的标记,是不是超级麻烦
Nitroethane
2022-10-06 23:21:50 +08:00
@gulu #5 写内核模块才能这样搞,用户态进程肯定不行。

解析 /proc/[pid]/maps 文件,从这个文件中可以知道进程的虚拟地址空间布局,包括 stack 和 heap 的地址范围。
ColorfulBoar
2022-10-07 02:11:53 +08:00
正常人的裸指针不带 ownership (当然喜欢指针的没一个正常人就是了)
另外在内存哪个区域和 storage duration 是两码事,比如如果外面是个 coroutine 那即使已经知道是 automatic storage duration+没有重载 operator new ,也可能被分配在堆上(同时编译器也可能优化成在栈上)
mingl0280
2022-10-07 09:20:44 +08:00
不要删就完了。
谁分配的谁清理。
dearmymy
2022-10-07 09:39:40 +08:00
开始想判断堆跟栈 地址,但想想如果这个整个都 new 在堆里。
感觉靠谱的,得栈帧一步步回溯?然后判断堆地址区间?
iceheart
2022-10-07 09:52:39 +08:00
通过调用栈取到最接近栈顶的地址,定义一个栈上的变量,取到这个变量的地址。在此区间的指针就是栈上的
littlewing
2022-10-07 10:51:55 +08:00
在堆上也不一定要 delete 啊,说不定创建者自己要 delete 呢,说白了还是 ownership 的问题,建议你用 unique_ptr 或 shared_ptr 。一定要用裸指针的话,遵循谁 new 谁 delete 的原则,除非是在异步回调里
wtsamuel
2022-10-07 11:32:02 +08:00
那应该去问创建这个指针的人
还得讨论下应不应该修改, 删除这个指针的值
whi147
2022-10-07 11:39:36 +08:00
谁创建谁清理,全部更换智能指针,少用共享智能指针
calloc
2022-10-07 11:39:51 +08:00
去 /proc/self/maps 比对一下
yolee599
2022-10-07 12:57:36 +08:00
谁创建谁清理原则,不要随便 delete 别人传进来的指针

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/884939

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX