2

假设我有以下函数,它有一个类型为 T 的参数。该参数的生命周期是多少。

int* f()
{
   int x=0;
   int* ptr=&x;
   return ptr; //i know this is undefined behavior.
}

所以在f()函数中,当它被调用时,本地表达式将运行并且范围指向值的结尾将被删除。但我的问题是针对以下功能

void f2(int* y)
{
}
int main()
{  
   int p=0;
   f2(&p);
   cout<<p<<endl;
   return 0;
}

这里,当我们调用f2()的时候那个参数int* y会被删除?因此,如果它删除的逻辑指向的值将被删除,即 p,为什么我可以使用 cout 看到 p 的值相同?那么f2的论点什么时候会被删除呢?什么时候函数的结束范围?或者是什么?

4

5 回答 5

9

void f2(int* y)中,您有一个指针的副本。该指针对象的生命周期y延伸到函数的末尾f2

在您的main函数中,您有一个 integer p。的生命周期p延长到main.

调用时f2(&p),会创建一个临时指针以传递给f2. 它不会修改p. 因此,当f2返回时,临时指针不再在范围内,但p 仍在范围内(因此有效)。

显示的所有变量都有自动存储持续时间,不需要明确的“删除”。

于 2013-11-08T18:34:22.247 回答
3

该函数不对您传递的参数进行内存管理,除非参数是按值传递的(从技术上讲,c++ 中的所有内容都是按值传递的,除了引用,但在指针的情况下,不需要清理太多)。如果您的代码p在 main 范围结束时被破坏。请记住,这是因为p如果它具有动态存储,则它具有自动存储,只有在您对其调用 delete 时才会将其删除。

现在通常没有理由将自动变量作为 ptr 传递,因为 c++ 有一个很棒的东西,称为按引用传递

void f2(int& y)  

这是你在大多数情况下应该做的

于 2013-11-08T18:34:00.553 回答
2

函数参数只是函数体块范围内的局部变量。函数参数和普通块作用域变量的区别在于,在函数体开始执行之前,函数参数是从对应的函数调用表达式中初始化的。

变量的生命周期y仅在函数体的执行期间延伸f

名为指针对象的对象所指向的对象y具有与 完全无关的生命周期y

于 2013-11-08T18:34:02.617 回答
1

p输入时在堆栈上创建main。你打电话f并将地址传递p给它。的f参数y获取这个地址。y也存储在堆栈中。f返回时,因为y它是局部变量而被删除,但p仍然存在并且您打印它的值。与 类似y,局部变量在退出p时被删除。main

于 2013-11-08T18:33:51.030 回答
1

指针不会在范围结束时自动“删除”(在delete运算符应用于它们的意义上)。包含地址本身的变量将被删除,但它指向的数据不会。

您可能会查看std::unique_ptr,它符合您的描述。

于 2013-11-08T18:35:02.580 回答