假设我这个指针在 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 。。我知道最简单的方法肯定是你就不要这么写
1
lmshl 2022-10-06 22:48:27 +08:00 via iPhone
按 c++ move 写不就行了?
|
2
lmshl 2022-10-06 22:49:34 +08:00 via iPhone
不使用 move 的话,比较简单的原则是谁创建谁销毁
|
3
yanqiyu 2022-10-06 22:55:49 +08:00
真的写出这种代码的话给调用者带来的迷惑不是一点半点...
堆栈生长方向不一样,你随便把这个指针和局部变量比大小就行,毕竟是 caller 传给你的 但是不要这么做,最好要么始终不转移所有权,要么始终转移所有权,要么用智能指针 |
4
HFcbyqP0iVO5KM05 2022-10-06 22:57:09 +08:00 via iPhone
|
5
HFcbyqP0iVO5KM05 2022-10-06 23:01:31 +08:00 via iPhone 1
判断一个内存段是否属于 heap ,需要借用 mm_struct 里面的 start_brk(heap 内存段的开始位置) 和 brk(heap 内存段的结束位置)。vma 的开始和结束地址在 mm_struct 的 start_brk 和 brk 之间,则说明地址在 heap 内存中。
|
6
leimao 2022-10-06 23:09:08 +08:00
> 那我在 class 里面怎么优雅地判断是哪一种情况?(要不要析构的时候销毁这三个 new ?)
最好不要这么干,object 不 own 那些 memory ,就别去干 delete 的事。 |
7
heiher 2022-10-06 23:15:20 +08:00 via Android
c++不用自动内存管理,就要显式约定 ownership ,不需要判断
|
8
BrettD 2022-10-06 23:16:27 +08:00 via iPhone
你这样写还这样问就说明没有把所有权归属问题想清楚
|
9
leonshaw 2022-10-06 23:16:40 +08:00
你也知道不要这么写,所有权也是函数 contract 的一部分。并且完全可以分配一块堆内存作为线程的栈(默认情况也是和堆类似分配方式)。
|
10
shawnsh 2022-10-06 23:19:46 +08:00 via Android
谁创建的指针,谁知道是用的哪个区,让他管回收,你只是使用,你不要管回收。如果要回收,那么就需要知道该指针的类型,是哪个区的。所以你要封装个对象,里面要有一个指针,还要有指针所在的区域,还要有是否调用者可以释放的标记,是不是超级麻烦
|
11
Nitroethane 2022-10-06 23:21:50 +08:00 1
|
12
ColorfulBoar 2022-10-07 02:11:53 +08:00
正常人的裸指针不带 ownership (当然喜欢指针的没一个正常人就是了)
另外在内存哪个区域和 storage duration 是两码事,比如如果外面是个 coroutine 那即使已经知道是 automatic storage duration+没有重载 operator new ,也可能被分配在堆上(同时编译器也可能优化成在栈上) |
13
mingl0280 2022-10-07 09:20:44 +08:00 via Android
不要删就完了。
谁分配的谁清理。 |
14
dearmymy 2022-10-07 09:39:40 +08:00
开始想判断堆跟栈 地址,但想想如果这个整个都 new 在堆里。
感觉靠谱的,得栈帧一步步回溯?然后判断堆地址区间? |
15
iceheart 2022-10-07 09:52:39 +08:00 via Android
通过调用栈取到最接近栈顶的地址,定义一个栈上的变量,取到这个变量的地址。在此区间的指针就是栈上的
|
16
littlewing 2022-10-07 10:51:55 +08:00
在堆上也不一定要 delete 啊,说不定创建者自己要 delete 呢,说白了还是 ownership 的问题,建议你用 unique_ptr 或 shared_ptr 。一定要用裸指针的话,遵循谁 new 谁 delete 的原则,除非是在异步回调里
|
17
wtsamuel 2022-10-07 11:32:02 +08:00
那应该去问创建这个指针的人
还得讨论下应不应该修改, 删除这个指针的值 |
18
whi147 2022-10-07 11:39:36 +08:00 via iPhone
谁创建谁清理,全部更换智能指针,少用共享智能指针
|
19
calloc 2022-10-07 11:39:51 +08:00 via iPhone
去 /proc/self/maps 比对一下
|
20
yolee599 2022-10-07 12:57:36 +08:00 via Android 1
谁创建谁清理原则,不要随便 delete 别人传进来的指针
|
21
FrankHB 2022-10-07 16:35:01 +08:00
你要优雅,就先干掉 computer::computer(cpu*, gpu*, memory*)这种看不出让你怎么干的废物签名。
基本上除非在写分配器的实现,你一个一般应用的作者,没什么理(资)由(格)在 API 中用指针。 (写内核之类的东西原则上几乎都得依赖 ABI ,使用的假设比 C++的指针多得多。) |
22
hu8245 2022-10-08 09:42:55 +08:00 via Android
我实在想不出什么普通场景需要这种骚操作,你操作了,人家释放的时候出问题了,算函数内的操作还是 caller ?
|