1

これに対する解決策がどこにも見つかりませんでした。このテーマについてもっと啓発されることを願っています。

arduino プロジェクトに動的配列の並べ替えを使用したいと考えていました。ここでarduinoプラットフォームでベクトルを使用するためのライブラリに出会いました。hereを見つけたarduinoの空きRAMを監視する機能を使用しました。

これが私のコードの例です:

Serial.print("Starting RAM: ");
Serial.println(freeRam());
Serial.println();

vector<int> intVector;

Serial.print("Remaining RAM after intVector declaration: ");
Serial.println(freeRam());
Serial.println();

vector<char> charVector;

Serial.print("Remaining RAM after charVector declaration: ");
Serial.println(freeRam());
Serial.println();


Serial.print("sizeof(intVector) = ");
Serial.println(sizeof(intVector));
Serial.print("sizeof(charVector) = ");
Serial.println(sizeof(charVector));

出力は次のとおりです。

Starting RAM: 1684

Remaining RAM after intVector declaration: 1618

Remaining RAM after charVector declaration: 1584

sizeof(intVector) = 7
sizeof(charVector) = 7

intVector の割り当てが RAM の 66 バイトのチャンクを占有したようです。ベクトルは、このために 32*2 + 2 = 66 バイトのメモリを割り当てているようです。同様に、charVector の割り当てには 34 バイト (32*1 + 2) が必要でした。32* + change を割り当てるこのパターンはsizeof(type)、他のデータ型 (char、float など) にも存在するようです。sizeof(int) = 2arduinoで注意してください。

私の問題は、これらのベクトルに入力したいオブジェクトが 10 ~ 20 バイトの大きさであることです。ATMega328 で使用できる RAM は 2 kB しかないため、現在設計されているプログラムを実行することはできません。を持つオブジェクトの場合segmentsizeof(segment) = 16ベクトルは 522 バイトの RAM ブロックを消費します。

だから私の質問は:

  1. ベクトルのサイズが 7 バイトしかないのに、そのタイプにもかかわらず、ベクトルが 32 * sizeof(type) バイトの RAM を割り当てるのはなぜですか?

  2. arduino プラットフォームで一種の動的配列を使用するより良い方法はありますか?

  3. ベクトルを使用できるメモリ管理手法はありますか?

この質問が重複している場合は、事前に申し訳ありません。

編集:

ベクターは容量32で初期化されているようです。

intVector.capacity() = 32;

どちらかを使おうとする

intVector.reserve(1); // or
intVector.resize(1);

ベクトルの容量は変更されません。

4

3 に答える 3

5

ベクトルは、効率のために一度に必要以上のスペースを割り当てます。単一のアイテムを挿入しようとするたびに再割り当てする必要はありません。まだ空であっても、32 項目の容量で初期化される可能性は十分にあります。

プリントアウトvec.capacity()して、確保されている要素の数を確認してください。

ベクターは、標準コンテナーの中で最もスペース効率が高く、各要素に必要な量と一定のオーバーヘッドのみを使用する必要があります。

于 2012-12-06T17:31:13.980 に答える
2

そのvector実装をざっと見てみると、常に余分な__UCLIBCXX_STL_BUFFER_SIZE__バイトのメモリが予約されていることがわかります。そのプリプロセッサ シンボルは のように定義さ32system_configuration.hます。

したがって、デフォルトの a の構築は、vector常に 32 バイトとvector、割り当てられたメモリ、サイズ、容量などを追跡するために必要なオーバーヘッドを消費します。

プリプロセッサの定義を次のように変更してみてくださいsystem_configuration.h

#define __UCLIBCXX_STL_BUFFER_SIZE__ 0

ただし、このスペースが常に割り当てられていることに依存するものがある場合、これはコードを壊す可能性があります。

于 2012-12-06T17:50:41.827 に答える
0

他の回答で述べたように、 std::vector は、挿入するたびに再割り当てを防ぐために、常に事前にメモリを割り当てます。システムにメモリの追加を要求するのはコストのかかるプロセスであり、できる限り避けたいものです。

カスタム アロケータを記述します。アロケータは std::vector のオプションのテンプレート引数であり、それを使用してメモリを取得する方法を再定義できます (たとえば、事前割り当てを少量にする、挿入ごとに再割り当てするなど)。詳細については、STLの Nicolai Josuttis のWeb サイトを参照してください。アロケーターを網羅した無料の章(サイドバーのヘッダー「補足章(PDF)」)と、サンプルコードもあります。

于 2012-12-06T18:00:20.943 に答える