独占指针在堆上还是栈上分配内存?

4

我是C++的新手,我在电脑上测试了一个独立指针:我以为它会被分配到堆上,但实际上它出现在了栈里。这让我感到困惑。那么,独立指针是在堆上还是栈上分配内存的呢?

    #include <memory>
    #include <stdio.h>

    void RawPointer()
    {
        int *raw = new int;// create a raw pointer on the heap
        printf("raw address: %p\n", raw);
        *raw = 1; // assign a value
        delete raw; // delete the resource again
    }

    void UniquePointer()
    {
        std::unique_ptr<int> unique(new int);// create a unique pointer on the stack
        *unique = 2; // assign a value
        // delete is not neccessary
        printf("unique pointer address: %p\n", &unique); 
    }

    int main(){
        RawPointer();
        UniquePointer();
    }

它是以 shell 形式出现的:

    raw address: 0x555cd7435e70
    unique pointer address: 0x7ffcd17f38b0

感谢您们兄弟们,


1
一个独特指针并没有分配任何内容,它只是保持了对某个东西的指针,这个东西可以在堆上或栈上。独特指针本身可以在堆上或栈上。使用new进行分配意味着堆分配。 - Klaus
“但它显示在堆栈上”是什么?你的结论不够清晰。如果这导致了混淆,那么unique_ptr和它所封装的指针之间存在差异。 - 463035818_is_not_a_number
谢谢,这意味着我可以将unique作为一个类来考虑,在int指针内部指向堆。我是对的吗? - kit_J
2个回答

1
你在UniquePointer函数中打印的是std::unique_ptr类对象的地址。这个类有一个内部成员,即分配数据的实际地址。你可以使用get()成员函数访问这个实际地址,如下面的代码所示(当我尝试时,它给了我与原始指针完全相同的地址,但并不总是这样)。
void UniquePointer()
{
    std::unique_ptr<int> unique(new int);// create a unique pointer on the stack
    *unique = 2; // assign a value
    // delete is not neccessary
 // printf("unique pointer address: %p\n", &unique);
    printf("unique pointer address: %p\n", unique.get());
}

注意:格式说明符%p需要一个void *指针作为参数;但是,将另一种类型的指针隐式转换void指针是定义良好的行为-请参见此处:void pointers: difference between C and C++

如有进一步的澄清和/或解释,请随时提问。


0
在你的例子中,rawunique是本地变量,分配在堆栈上,你可以在打印变量地址时进行检查。
printf("raw pointer address: %p\n", (void*)&raw);
printf("unique pointer address: %p\n", (void*)&unique);

但是指针rawunique可以指向任何地方。如果它们指向使用new分配的对象,则指针指向堆上的对象。当打印指针值时,您可以看到这一点。

printf("raw pointer points to: %p\n", (void*)raw);
printf("unique pointer points to: %p\n", (void*)unique.get());

请注意,我在传递给printf的指针上添加了(void*)转换,因为如果我记得正确,%p需要一个void*

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接