简体   繁体   English

如何在函数返回之前删除指针?

[英]How to delete a pointer before return it in a function?

If we have a function like this: 如果我们有这样的函数:

int* foo()
{
  int *x;
  x = new int;

  delete x;
  return x;
}

We need to return a pointer in a function, but what we have learned is we need to delete a space in the final. 我们需要在函数中返回一个指针,但我们学到的是我们需要在final中删除一个空格。

If we delete x first as above, then is it meaningful to return x in the final line? 如果我们首先删除x ,那么在最后一行返回x是否有意义? Because the x does not exist anymore. 因为x不再存在。

But if we don't delete x before return, the function will be finished. 但是如果我们在返回之前不删除x ,则该函数将完成。

How can we do? 我们怎么办? Or we don't really need to delete a space which was allocated in the memory? 或者我们真的不需要删除在内存中分配的空间?

You do need to delete the pointer at some stage, but that does not have to be in the same function scope where you new it. 您确实需要在某个阶段delete指针,但这不一定在您new它的同一函数范围内。 It can happen outside of your function, which I think is what you're trying to achieve. 它可能发生在你的功能之外,我认为这是你想要实现的。

int* foo()
{
  int *x;
  x = new int;
  return x;
}

int *px = foo();
// use px in some way
delete px;

if we delete x first as above, then is it meaningful to return x in the final line? 如果我们先如上所述删除x,那么在最后一行返回x是否有意义? because the x does not exist anymore. 因为x不再存在了。

Two things here, first no it is not meaningful to return x after delete x; 这里有两件事,首先没有delete x;后返回x没有意义delete x; and secondly, deleting x won't delete the x itself, it will only free up the memory to which the x points to. 第二,删除x不会删除x本身,它只会释放x指向的内存。

or we don't really need to delete a space which was allocated in the memory? 或者我们真的不需要删除在内存中分配的空间?

Wrong. 错误。 You need to free up every dynamically allocated memory location. 您需要释放每个动态分配的内存位置。

but if we don't delete x before return, the function will be finished. 但如果我们在返回之前不删除x,则该函数将完成。 how can we do ? 我们该怎么办?

What you can do is declare the pointer outside the function and then after you have returned the pointer x from the function, then you can delete it anywhere outside that function which returned the pointer. 你可以做的是在函数外部声明指针,然后在从函数返回指针x之后,你可以在返回指针的函数之外的任何地方删除它。

Tip: Consider using Smart Pointers because along with other benefits, one of the biggest benefit of using Smart Pointers is that they free up the allocated memory automatically and save you the headache of freeing up the memory explicitly. 提示:考虑使用智能指针,因为除了其他好处之外,使用Smart Pointers的最大好处之一是它们可以自动释放分配的内存,并且可以省去显式释放内存的麻烦。

There is absolutely no reason at all to delete the pointer before returning it. 在返回之前完全没有理由删除指针。 The only thing you will get is the memory address to a piece of memory that was allocated but no longer is. 你唯一能得到的就是分配但不再存在的内存的内存地址。

It would make sense in this code: 这段代码有意义:

main()
{
   int *ptr = foo()
   cout << "The memory address that function foo got "
        << "allocated to a local pointer is " << ptr << endl;
}

But come on, who would ever want to write such a thing? 但是,来吧,谁会想写这样的东西?

It is, however perfectly ok to delete after the function call, like so: 但是,在函数调用之后删除是完全可以的,如下所示:

int* ptr = foo();
delete ptr;

What you need to understand is that delete does not remove a pointer. 您需要了解的是delete不会删除指针。 What it does is to say "I (the program) am done with whatever this pointer is pointing to. You (the os kernel) can use it for anything now. I will not do anything more with that address. I promise." 它的作用是说“我(程序)完成了这个指针所指向的任何东西。你(os内核)现在可以用它做什么。我不会再用那个地址做任何事了。我保证。” to the operating system. 到操作系统。 You do not have to have one delete for every pointer. 您不必为每个指针删除一个。 This is completely ok, and causes no memory leaks: 这是完全正常的,并且不会导致内存泄漏:

  int *p=new int;
  int *a[3]={p, p, p};
  int n;
  cout << "Via which pointer in array a do you "
       << "want to delete the allocated memory? ";
  cin >> n;
  delete a[n];

It is pretty silly code, but it shows my point. 这是非常愚蠢的代码,但它显示了我的观点。 It is not about the pointer. 它不是关于指针。 It's about what the pointer is pointing at. 这是关于指针指向的内容。

And remember one thing. 记住一件事。 A pointer does not get the value NULL when you delete it. 删除指针时,指针不会获得NULL值。 You have to take care of that separately. 你必须分开处理。

Variables declared in the scope (between the {} ) of the functions are distroyed when leaving the function, as they are built on the stack memory of the function. 在函数范围内(函数之间)声明的变量在离开函数时被破坏,因为它们构建在函数的堆栈内存中。

When using new(), memory is allocated on the heap, another memory space independant from the function. 使用new()时,内存在堆上分配,另一个内存空间与函数无关。

This memory won't be freed before you delete the pointer pointing this memory, that's why once using a new(), you'll have to get the pointer deleted before your app returns. 在删除指向此内存的指针之前,不会释放此内存,这就是为什么一旦使用new(),您必须在应用程序返回之前删除指针。

Returning a deleted pointer doesn't make sense unless you want your application to crash. 除非您希望应用程序崩溃,否则返回已删除的指针没有意义。 Dereferencing (accessing) a deleted pointer can lead to application crash or memory corruption. 取消引用(访问)已删除的指针可能会导致应用程序崩溃或内存损坏。

If the purpose of your function is to provide a valid pointer on some type, the delete will have to occur outside of the function, once you wont need to use the variable anymore. 如果函数的目的是在某种类型上提供有效的指针,那么一旦你不再需要使用变量,删除就必须在函数之外进行。

Two last tips: 最后两个提示:

  • don't delete a pointer twice, this would cause a crash. 不要删除指针两次,这会导致崩溃。
  • assigning 0 to a deleted (or non allocated) pointer can be a guard: 将0分配给已删除(或未分配)的指针可以是一个保护:

ex: 例如:

int * pt = 0;

pt = new int;
*pt = 12;

delete pt;
pt=0;

if (pt==0) {
   // the pointer doesn't point to anything, and we can test it safely
}

/* ... */

if (pt!=0) {
    delete pt; //this second delete wont occur if pt is null (==0)
    pt=0;
}

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

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