可以使用delete释放通过值返回主函数的内存吗?

时间:2013-03-30 21:09:01

标签: c++ visual-c++

当我了解它时,我理解这一点的方式是C ++关键字delete只能安全地删除由new分配的内存。我想知道你是否可以通过函数返回一个struct,并在main中删除它。这是我要问的一个例子......

#include <stdio>
#include <new>
using namespace std;

struct structure {
   int i;
   float f;
}

struct get_struct();

int main() {
   structure structure_1;
   structure_1 = get_struct();

   delete &structure_1;
   return 0;
}

struct get_struct() {
   struct test_struct = new struct;
   return test_struct;
}

我知道我只能从函数返回一个指针,并在main中指定一个指针指向函数的返回值,这不是我所要求的。我也尝试使用...

删除
delete &struct;

但这不起作用,我收到Visual Studio错误。

所以我要问的是,有没有人知道用new返回一个函数结构的方法,并使用delete来释放main中的那个内存。也许这是一项非常简单的任务,但我很难过。谢谢大家!

2 个答案:

答案 0 :(得分:0)

经过一番思考,我正在将正确的解决方案移到顶端:

struct S { int a; S(int a) : a(a) { } };
S foo () { return S(5); }

int main() {
    S s = foo();
}

此解决方案不会复制S;它将被移动而不是。由于它不涉及手动内存管理,因此更安全,因此建议使用。


如果这是一项愚蠢的任务,你绝对必须使用new

struct S {};

S* foo () { return new S; }

int main () {
    S* ptr = foo();
    delete ptr;
}

但它不被认为是现代C ++;您可以安全地按值返回,因为编译器将选择退出任何副本。

答案 1 :(得分:0)

一般部分

您的问题的一般答案是,您不能。

  • newdelete运算符始终处理指针,而不是任何其他值类型。

  • 您永远不必手动删除任何值类型,而且永远不会,永远不会(!)曾尝试过。

原因是,用于存储任何值的内存是从主内存的不同部分分配的,作为用于存储new运算符返回的指针值的内存。

一旦程序流进入函数,将自动分配用于存储函数中使用的值 stack 的内存位置,并在函数离开后自动清理。

(当然,内部还有一些工作要做,但你永远不必自己处理它,因为编译器会生成所需的设置和清理代码)

用于存储用new运算符生成的指针的值的内存是从内存的另一部分(通常称为 heap )分配的,不会自动获取根本就清理干净了。

以你的例子

看看你的示例代码:

struct get_struct() {
   struct test_struct = new struct;
   return test_struct;
}

第一个问题是,即使在修复了一些语法错误之后:

struct structure get_struct() {
   struct structure test_struct = new structure;
   return test_struct;
}

代码不会编译,编译器会抛出一些错误,如:

error: conversion from ‘structure*’ to non-scalar type ‘structure’ requested

使用new structure而不是值,但只有指向该值的指针才可用。 要使这两种类型匹配,您必须使用struct strcuture *test_test = new structure;仍然按值返回,您可能会想到这样做:

struct structure get_struct() {
   struct structure *test_struct = new structure;
   return *test_struct;
}

以值为单位返回,为test_struct分配数据的副本。

这种方法的问题是,现在你已经产生了一个记忆漏洞,你将会仔细看看会发生什么:

  • 在输入函数时,将在堆栈上分配足够的内存来保存指向struct structure的指针的值。
  • new opertor将分配一些内存来保存上的struct structure,这是我已经讨论过的内存的其他部分的通用名称。< / LI>
  • 指向此内存位置的指针将存储在test_struct

  • 将生成test_struct指向的struct结构的副本。

  • 分配用于在输入函数时将指针值存储到struct structure的内存将被释放。

这种方法的问题在于,只保留get_structure指针,而不是指向的数据被返回给系统。因为你没有保留任何副本,因为没有机会再次在任何delete语句中引用内存,因此内存实际上已丢失。

发生的事情如下:

             call to                    return
  main()    --------->  get_struct()    -------->
           get_struct()                            
 STACK
  +--------------+      +--------------+        +--------------+
  | structure_1; |      | structure_1  |        | structure_1  |
  +--------------+      +--------------+        +--------------+
  |              |      | ...          |        |              |
                        |              |
                        | test_struct *--+
                        +--------------+ | 
                        |              | |
                                         |              
 HEAP                                    |
                                         |
  |              |      |              | |      |              |
  |              |      +--------------+ |      +--------------+
  |              |      | structure    |<+      | structure    |
  |              |      | data         |        | data         |
  +--------------+      +--------------+        +--------------+

为了防止记忆丧失,您在离开delete之前必须get_structure(),可能会使用以下内容:

struct structure get_struct() {
   struct structure *test_struct = new structure;
   struct ret = *test_struct;

   delete test_struct;
   return ret;
}