我提供了两种方法来向我的集合添加元素,每个const引用一次,每个指针一次。
void push_back(const value_type *val) {
element *elem = new element(val);
//...
}
void push_back(const value_type &val) {
push_back(&val);
}
element
类将值保存为指针。
class element {
private:
const value_type *value;
public:
element(const value_type *value):
value(value) {
}
~element() {
delete value;
}
显然,当弹出元素或删除集合时,如果将元素添加为指针,则必须释放内存。 但是,如果未手动分配元素并通过引用传递,则会产生错误。
如果在push_back时间动态分配元素,是否还有其他选项可以解决此问题?
答案 0 :(得分:1)
保持一致并始终存储可以删除的指针。
void push_back(const value_type &val) {
push_back(new value_type(val));
}
答案 1 :(得分:1)
一般来说,这是一个有缺陷的设计。您可以通过不同的方式更改设计以实现所需。 马克的答案是一种直接的方式,例如。
话虽如此,这是使用您的设计的可能解决方案。再一次,我不推荐它,因为它依赖于编译器如何构建堆栈的内部,并且不能跨编译器/平台移植。
基本上,在~element()
中,您可以通过将它与当前堆栈指针进行比较来检查存储在value
中的地址是在堆栈上还是在堆上。如果存储在value
中的地址高于堆栈指针,则它在堆栈上并且不应被删除(提供堆栈在地址空间顶部的通常位置)。如果它小于堆栈指针 - 它在堆上。
用于说明地址关系的代码(GCC,x64 linux):
#include <iostream>
int main()
{
int * heap_(new int(0));
int stack_(0);
void * rsp_(nullptr);
asm("mov %%rsp, %0" : "=m" (rsp_));
std::cout << "heap address\t: " << heap_
<< "\nstack address\t: " << &stack_
<< "\nstack pointer\t: " << rsp_ << std::endl;
delete (heap_);
return (0);
}
节目输出:
heap address : 0xc52010
stack address : 0x7fff528ffee4
stack pointer : 0x7fff528ffee0
ideone.com可以访问GCC,但使用x86版本 - esp
注册而不是rsp
。 The code has to be changed(不可移植性)。