-5

これを知ったときに私がこれを理解した方法は、C++ キーワード delete は、new によって割り当てられたメモリのみを安全に削除できるということでした。関数から構造体を値で返し、メインで削除できるかどうか疑問に思っています。これが私が尋ねていることの例です...

#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;
}

関数からポインターを返すだけで、関数の戻り値を指すポインターをメインに割り当てることができることはわかっていますが、それは私が求めていることではありません。私も使用して削除しようとしました...

delete &struct;

ただし、これは機能せず、Visual Studio エラーが発生します。

だから私が求めているのは、newで値によって関数から構造体を返し、deleteを使用してメインのそのメモリを解放する方法を知っている人はいますか? 多分それは非常に単純な作業ですが、私は困惑しています。みんな、ありがとう!

4

2 に答える 2

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++ とは見なされません。コンパイラはすべてのコピーをオプトアウトするため、安全に値で返すことができます。

于 2013-03-30T21:13:01.117 に答える
0

一般部

あなたの質問に対する一般的な答えはノーです。できません。

  • newand演算子はdelete、他の値の型ではなく、常にポインターを扱います。

  • 手動で値の型を削除する必要はありません。実際に、絶対に、絶対に (!) 削除しようとするべきではありません。

その理由は、任意の値を格納するために使用されるメモリは、メイン メモリの別の部分から割り当てられ、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に保持するメモリを割り当てます。struct structure
  • このメモリ位置へのポインタは test_struct に格納されます

  • test_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;
}
于 2013-03-30T22:26:42.253 に答える