处理已分配和堆栈内存

时间:2013-09-04 21:00:37

标签: c++

我提供了两种方法来向我的集合添加元素,每个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时间动态分配元素,是否还有其他选项可以解决此问题?

2 个答案:

答案 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注册而不是rspThe code has to be changed(不可移植性)。