12

C++ でプロジェクトを開始しました。この言語でのメモリ管理は、私にとって初めてのことです。

以前はオブジェクトを作成しnew ()てポインターを渡していましたが、それが機能している間はデバッグが面倒で、コードを見たときに変な目で見られました。リークやセグメンテーション フォールト (修正後) が発生しなかったことは非常に誇りに思っていますが、これには本当に多くの労力が必要でした。

list <struct Connection *> users;

struct Connection * accept_connection (const char *name) {
  struct Connection * new_node = new Connection ();
  new_node->_data = ... // whatever, set it up here
  return new_node;
}

struct Connection * new_user = accept_connection (const char *name);
users.append (new_user);

そのため、このプロジェクトの次のバージョンの新しい戦略があります。これまでのところ、オブジェクトを作成new ()して一意の整数 ID 番号を割り当てています。次に、ID をキーとして使用して、オブジェクトをハッシュ テーブルに格納します。アイテムは格納され、整数の ID 番号で渡されます。逆参照する必要がある場合は、ハッシュ テーブルに移動すると、thing *またはが返されますNULL。したがって、ポインター エラーは発生しなくなりましたが、コードの速度は多少低下します。

typedef unsigned long ID_Number;

// create a user and return the ID
ID_Number create_user () {
  ID_Number new_id = assign_unique_id ();
  struct User * node = new User ();
  node->_id = new_id;
  node->_data = ... // whatever, set it up here
  add_to_users_dict (new_id, node);
  return new_id;
}

list <ID_Number> users;

for_each (users.begin(), users.end(), process_user);

void process_user (ID_Number i) {
  struct User * u_ptr = lookup_user_dict (i);
  if (u_ptr == NULL) {
    // not found in dict
    // somehow this guy was deleted
  } else {
    // we can do stuff with this guy
  }
}

現在、私はプログラミングの基本的な教義にはある程度精通していますが、独学の愛好家であるため、業界の慣行やツールには精通していません。私が基本的に求めているのは、メモリ管理に関するガイドラインです。

1) 私は何を正しく、または間違っているのか?

2) 役立つパッケージやライブラリはありますか?

3) 業界の標準的な慣行は何ですか?

4) 基本的に何をグーグルで検索したり、kindle などで購入したりする必要がありますか?

今日、私は通常Pythonを使用しています。多くの「バックエンド」を処理しますが、CまたはC ++が必要です(プレーンCとstdc ++ライブラリを使用していると思います。言語は-g ++が正常にコンパイルされることを知っているだけです)速度/パフォーマンス上の理由から、この特定のプロジェクトの場合:数学の天才の中には、それを際限なく高速化するアルゴリズム修正を提供できると思いますが、それは別の質問です.

4

4 に答える 4

9

私ができる最善の答えは、従来の方法でポインターを使用するべきではないということです。C++11 は、プログラマがメモリ管理を扱う方法を変更しました。

私よりもはるかに知的な人々によってすでに詳細に説明されていることを説明するのではなく、いくつかのリンクを提供するだけです.

最初にご覧いただきたいのは、Herb Sutter の Article Elements of Modern C++ Style です 。次に、Bjarne Stroustrup C++11 Styleによるビデオをご覧ください。

新しい C++11 標準を使用できる場合は、メモリ管理が以前よりもはるかにクリーンになります。

于 2012-05-22T16:16:08.790 に答える
2

私は何を正しくまたは間違っていますか?

基本的に、直接ポインターの代わりにハンドルを使用してオブジェクトを参照するシステムを作成しました。これは、いくつかのシナリオに適しています。オペレーティング システムは、OS がオブジェクトを "所有" し、その有効期間を管理するが、クライアントがそれを参照できるようにする場合に、ハンドルを使用することがよくあります。

役立つパッケージやライブラリはありますか?

最新の C++ の標準ライブラリには、動的オブジェクトの有効期間を管理するスマート ポインターである shared_ptr と unique_ptr があります。これらは RAII を使用する優れた方法です。

業界の標準的な慣行は何ですか?

C++ のデファクト スタンダードは RAII です。リソース割り当ては初期化です。RAII は、割り当てをコンストラクターに結び付け、割り当て解除をデストラクタに結び付けます。C++ には、c'tors と d'tors がいつどのように実行されるかについて確実な保証があるため、これにより、リークなしでオブジェクトの有効期間を管理する完璧な方法が得られます。スマート ポインターである shared_ptr と unique_ptr も、オブジェクトの所有権を明示的にします。

基本的に、キンドルなどのために何をグーグルまたは購入する必要がありますか?

RAII を検索します。

于 2012-05-22T16:17:52.643 に答える
2

最初のエラーは、を使用することnewです。

動的メモリが必要になることはめったになく、「直接」必要とされるよりもさらにまれです。ほとんどの動的に割り当てられたオブジェクトはコンテナー内に存在します (vectorや などmap)。

2 番目のエラーは、コンストラクターを使用しないことです。クラス不変条件とは何か、およびコンストラクターがそれらを有効にする方法を理解すれば、RAII (Resource Acquisition Is Initialization) を利用して C でのコーディングをやめることができます。

于 2012-05-22T16:19:14.737 に答える
1

1) 私は何を正しく、または間違っているのか?

Resource Acquisition Is Initialization (RAII) イディオムまたは最新の C++ 所有権セマンティクスを使用していません。

2) 役立つパッケージやライブラリはありますか?

実際にポインターを渡す必要がある場合は、std::unique_ptr と std::shared_ptr を使用できます。しかし、その前に、RAII セマンティクスを使用して独自のオブジェクトをリソース所有者として動作させる方法を学ぶ必要があります。

3) 業界の標準的な慣行は何ですか?

4) 基本的に何をグーグルで検索したり、kindle などで購入したりする必要がありますか?

ライイ

于 2012-05-22T16:17:27.743 に答える