简体   繁体   English

处理已分配和堆栈内存

[英]Handling allocated and stack memory

I provide two ways to add elements to my collection, once per const reference and once per pointer. 我提供了两种方法来向我的集合添加元素,每个const引用一次,每个指针一次。

void push_back(const value_type *val) {
    element *elem = new element(val);
    //...
}
void push_back(const value_type &val) {
    push_back(&val);
}

The element class holds the value as a pointer. element类将值保存为指针。

class element {
private:
    const value_type *value;
public:
    element(const value_type *value):
    value(value) {
    } 

    ~element() {
        delete value;
    }

Obviously when elements are popped or the collection is deleted, the memory has to be freed if elements were added as a pointer. 显然,当弹出元素或删除集合时,如果将元素添加为指针,则必须释放内存。 However, this yields an error when the elements were not manually allocated and passed by reference. 但是,如果未手动分配元素并通过引用传递,则会产生错误。

Is there any other option to solve this issue than additionally storing if the element is dynamically allocated on push_back time? 是否有任何其他选项来解决此问题,而不是另外存储如果元素是在push_back时间动态分配的?

Just be consistent and always store a pointer that can be deleted. 只是保持一致并始终存储可以删除的指针。

void push_back(const value_type &val) {
    push_back(new value_type(val));
}

It's a flawed design in general. 一般来说,这是一个有缺陷的设计。 And there are different ways you can change your design to achieve what you need. 您可以通过不同的方式更改设计以实现所需。 Mark's answer is a straightforward way to go about it, for example . 例如,马克的答案是一种直截了当的方式

That being said, here is a possible solution using your design. 话虽如此,这是一个使用您的设计的可能解决方案。 Once again, I do not recommend it as it relies on internals of how compilers build stack, and is not portable across compilers/platforms. 再一次, 我不推荐它,因为它依赖于编译器如何构建堆栈的内部,并且不能跨编译器/平台移植。

Basically, in ~element() you can check if the address stored in value is on stack or on heap by comparing it to the current stack pointer. 基本上,在~element()您可以通过将存储在value的地址与当前堆栈指针进行比较来检查它是存储在堆栈中还是堆栈上。 If the address stored in value is higher than the stack pointer then it's on stack and should not be deleted (provided usual location of the stack at top of address space). 如果存储在value的地址高于堆栈指针,则它在堆栈上并且不应该被删除(提供堆栈在地址空间顶部的通常位置)。 If it's less than stack pointer - it's on heap. 如果它小于堆栈指针 - 它在堆上。

Code to illustrate the relations of the addresses (GCC, x64 linux): 代码来说明地址的关系(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);
}

Program output: 节目输出:

heap address    : 0xc52010
stack address   : 0x7fff528ffee4
stack pointer   : 0x7fff528ffee0

ideone.com gives access to GCC, but uses x86 version - esp register instead of rsp . ideone.com允许访问GCC,但使用x86版本 - esp寄存器而不是rsp The code has to be changed (non-portability). 必须更改代码 (不可移植性)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM