假设我有以下函数,它有一个类型为T的参数。该参数的生命时间是什么。
int* f()
{
int x=0;
int* ptr=&x;
return ptr; //i know this is undefined behavior.
}
因此,在f()
函数调用时,将运行本地expressios,并删除范围结束的指向值。但我的问题是关注以下功能
void f2(int* y)
{
}
int main()
{
int p=0;
f2(&p);
cout<<p<<endl;
return 0;
}
此处,当我们在删除参数f2()
时调用int* y
时?因此,如果删除的逻辑上指向的值将被删除,这是p,为什么我可以使用cout看到p的值相同?那么什么时候f2的论点会被删除?当函数的结束范围?或者什么?
答案 0 :(得分:7)
在void f2(int* y)
中,您有一个指针的副本。指针对象y
的生命周期延伸到函数f2
的末尾。
在main
函数中,您有一个整数p
。 p
的生命周期延长到main
的结尾。
调用f2(&p)
时,会创建一个临时指针传递给f2
。它不会修改p
的生命周期。因此,当f2
返回时,临时指针不再在范围内,但p
仍在范围内(因此有效)。
显示的所有变量都有automatic storage duration,不需要明确的“删除”。
答案 1 :(得分:2)
该函数对你传递的参数没有内存管理,除非参数是通过值传递的(技术上一切都是通过c ++中的值传递,除了引用,但是在指针的情况下没有太多要清理的)。如果您的代码p
在主要范围结束时被破坏。请记住这是因为如果p
具有动态存储空间,则void f2(int& y)
具有自动存储功能,只有在您调用删除操作时才会将其删除。
现在一般来说没有理由将自动变量作为ptr传递,因为c ++有一个很棒的东西叫做引用传递
{{1}}
这是你在大多数情况下应该做的事情
答案 2 :(得分:2)
函数参数只是函数体块范围内的局部变量。函数参数和普通块作用域变量之间的区别在于,在正文开始执行之前,函数参数是从相应的函数调用表达式初始化的。
变量y
的生命周期仅延伸到函数体f
的执行。
名为y
的指针对象指向的对象具有与y
完全无关的生命周期。
答案 3 :(得分:1)
p
时,会在堆栈上创建 main
。您拨打f
并将p
的地址传递给它。 f
的参数y
获取此地址。 y
也存储在堆栈中。当f
返回时,y
会被删除,因为它是一个局部变量,但p
仍然存在并且您打印其值。与y
类似,当p
退出时,会删除本地变量main
。
答案 4 :(得分:1)
指针在示波器末尾自动不“已删除”(在delete
运算符应用于它们的意义上)。包含地址本身的变量将被删除,但它指向的数据不会被删除。
您可以查看std::unique_ptr
,它会执行您所描述的内容。