简体   繁体   English

为什么局部变量没有在这里销毁?

[英]Why isn't the local variable destroyed here?

I knew that when i am creating a variable inside a function, it gets destroyed immediately after the function call.我知道当我在 function 中创建一个变量时,它会在 function 调用后立即被销毁。 Why are p[0] and p[1] still equal to 123 if the pointer x got destroyed after f's call?如果指针 x 在 f 调用后被销毁,为什么 p[0] 和 p[1] 仍然等于 123?

#include <iostream>

using namespace std;

int *p;

void f()
{
    int *x;

    x = new int[2];

    x[0] = x[1] = 123;

    p=x;

    /// delete x;  if i delete x p[0] and p[1] are some kind of random int s;
}
int main()
{   f();

    cout<<p[0]<<p[1];

    return 0;
}

I knew that when i am creating a variable inside a function, it gets destroyed immediately after the function call.我知道当我在 function 中创建一个变量时,它会在 function 调用后立即被销毁。

Correct.正确的。

Why are p[0] and p[1] still equal to 123 if the pointer x got destroyed after f's call?如果指针 x 在 f 调用后被销毁,为什么 p[0] 和 p[1] 仍然等于 123?

Because the array of dynamic objects pointed by the destroyed pointer x is unaffected by the pointer being destroyed.因为被销毁的指针x指向的动态对象数组不受被销毁的指针的影响。

The dynamic array is not deleted at all and you have a memory leak.动态数组根本没有被删除,并且您有 memory 泄漏。

if i delete xp[0] and p[1] are some kind of random int s;如果我删除 xp[0] 和 p[1] 是某种随机 int s;

If you delete x , then p will be invalid and attempting to access through it results in undefined behaviour.如果您删除x ,则p将无效并尝试通过它进行访问会导致未定义的行为。


PS Avoid using bare owning pointers. PS 避免使用裸拥有的指针。 Also avoid unnecessary dynamic allocations.还要避免不必要的动态分配。

"Destroyed" in this case means that the variable x goes out of scope when the function ends, but it does not mean that the memory it points to is freed.在这种情况下,“已销毁”意味着当 function 结束时,变量x超出了scope,但这并不意味着它指向的 memory 是空闲的。 What's happening here is:这里发生的是:

  1. You assign x = p , so x and p both hold the same memory address and therefore point to the same memory allocation.您分配x = p ,因此xp都拥有相同的 memory 地址,因此指向相同的 memory 分配。
  2. x goes out of scope, but p doesn't, and nothing happens to the memory pointed to by p . x超出 scope,但p没有,并且p指向的 memory 没有任何反应。
  3. You use p to access the memory, which is perfectly valid since p has not gone out of scope and the memory it points to has not been freed.您使用p访问 memory,这是完全有效的,因为p尚未超出 scope 并且它指向的 memory 尚未被释放。

What's crucial to understand is that the variable x and the memory you allocated are two separate things with their own lifetimes, even though x points to the memory.理解的关键是变量x和您分配的 memory 是两个独立的东西,它们有自己的生命周期,即使x指向 memory。 x going out of scope doesn't free the memory, and likewise freeing the memory doesn't cause x to go out of scope. x going out of scope doesn't free the memory, and likewise freeing the memory doesn't cause x to go out of scope.

The way to "fix" your code without changing too much of it is to use std::shared_ptr<int[]> .在不更改太多代码的情况下“修复”代码的方法是使用std::shared_ptr<int[]>

#include <memory>
std::shared_ptr<int[]> p;

void f()
{
    auto x = std::make_shared<int[]>(2);

    x[0] = x[1] = 123;

    p=x;
}

On the other hand, if you intend for the heap-allocated memory to be released at the end of f() , then std::unique_ptr should be used:另一方面,如果您打算f()结束时释放堆分配的 memory ,则应使用std::unique_ptr

void f()
{
    auto x = std::make_unique<int[]>(2);

    x[0] = x[1] = 123;
}

Or, if your intent is to transfer ownership to p :或者,如果您的意图是将所有权转让给p

std::unique_ptr<int[]> p;

void f()
{
    auto x = std::make_unique<int[]>(2);

    x[0] = x[1] = 123;

    p=std::move(x);
}

Better yet is to avoid all of this entirely with std::vector更好的是使用std::vector完全避免所有这些

#include <vector>
std::vector<int> p;

void f()
{
    auto x = std::vector<int>(2);

    x[0] = x[1] = 123;

    p=std::move(x);
}

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

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