c++ 关于指针的作用域和它所指向的数据的混淆

b5buobof  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(120)

考虑以下简单的c++代码片段:

#include <iostream>
#include <memory>

std::unique_ptr<int> aPtr;

void simpleFunc()
{
    int aInt=10;
    aPtr = std::make_unique<int>(aInt);
}
int main()
{
    printf("Hello World");
    simpleFunc();
    
    std::cout<<"\nPrint: "<< *aPtr;
    return 0;
}

aPtr的作用域是全局的,而aInt的作用域是simpleFunc()的局部的。第一个问题是,我可以尝试使用仍然在作用域中的指针访问其作用域之外的局部变量吗?我试着打印这个值,它像预期的那样打印了10,但我不确定这是偶然的,还是值10实际上是有效的。
第二个问题是,是否有一种方法来检查一个内存位置是“空闲的”还是当前正在使用

lvmkulzt

lvmkulzt1#

第一个问题是,我可以尝试使用仍然在作用域中的指针访问其作用域之外的局部变量吗?
不你不能局部变量在堆栈上分配,因此一旦变量超出范围,它们占用的内存就不再可供使用。
然而,这并不是你的代码正在做的事情:

std::unique_ptr<int> aPtr;

void simpleFunc()
{
    int aInt=10;
    aPtr = std::make_unique<int>(aInt);
}

这将创建一个new int并将aInt的值存储在其中。所以aPtr不指向本地aInt。它指向一个新的int,它的值用10初始化。全局访问aPtr的值是安全的,因为它不指向该局部变量。
第二个问题是,是否有一种方法来检查一个内存位置是“空闲的”还是当前正在使用
这个问题需要更多的背景。一般来说,没有。这里的习惯用法是在释放nullptr之后设置指向它们的指针(并在声明它们时将它们初始化为nullptr),然后在需要时检查它们是否等于nullptr。这将是典型的:

// init to null so we know it points nowhere
    int *aPtr = nullptr;

    // example of testing for null
    if (!aPtr) { /* aPtr is null */ }

    // create an int, aPtr will no longer be null
    aPtr = new int;

    // when you free it, set it to null immediately 
    delete aPtr;
    aPtr = nullptr;

    // so now you know that aPtr is either a valid pointer, or it is null.
    // (except for that moment between delete and =nullptr, where it is garbage)

对于一个unique_ptr,它可以为你处理以上所有问题,你可以使用它内置的operator bool来检查它是否包含指针,例如:例如:

if (!aPtr) {
    // then aPtr is null (e.g. uninitialized or reset() was called to free)
}

另外,如果你使用的是std::shared_ptr,并且你有一个指向同一个对象的std::weak_ptrweak_ptr会让你知道共享指针何时被释放。

相关问题