0

コレクションに要素を追加するには、const 参照ごとに 1 回とポインターごとに 1 回の 2 つの方法を提供します。

void push_back(const value_type *val) {
    element *elem = new element(val);
    //...
}
void push_back(const value_type &val) {
    push_back(&val);
}

クラスはelement値をポインターとして保持します。

class element {
private:
    const value_type *value;
public:
    element(const value_type *value):
    value(value) {
    } 

    ~element() {
        delete value;
    }

要素がポップされるか、コレクションが削除されると、要素がポインタとして追加された場合、メモリを解放する必要があることは明らかです。ただし、要素が手動で割り当てられず、参照によって渡された場合、これはエラーを引き起こします。

要素がpush_back時に動的に割り当てられている場合、追加で保存する以外に、この問題を解決するオプションはありますか?

4

2 に答える 2

1

一般的には設計ミスです。また、必要なものを実現するためにデザインを変更するさまざまな方法があります。マークの答えは、たとえば.

そうは言っても、ここにあなたのデザインを使用した可能な解決策があります。繰り返しになりますが、コンパイラがスタックを構築する方法の内部に依存しており、コンパイラ/プラットフォーム間で移植できないため、お勧めしません。

基本的に、に~element()格納されているアドレスvalueがスタック上にあるかヒープ上にあるかは、現在のスタック ポインターと比較することで確認できます。格納されているアドレスvalueがスタック ポインターよりも高い場合、それはスタック上にあり、削除しないでください (スタックの通常の場所がアドレス空間の一番上にある場合)。スタック ポインターより小さい場合は、ヒープ上にあります。

アドレスの関係を示すコード (GCC、x64 Linux):

#include <iostream>

int main()
{
 int * heap_(new int(0));
 int stack_(0);
 void * rsp_(nullptr);

 asm("mov %%rsp, %0" : "=m" (rsp_));

 std::cout << "heap address\t: " << heap_ 
           << "\nstack address\t: " << &stack_ 
           << "\nstack pointer\t: " << rsp_ << std::endl;

 delete (heap_);

 return (0);
}

プログラム出力:

heap address    : 0xc52010
stack address   : 0x7fff528ffee4
stack pointer   : 0x7fff528ffee0

ideone.com は GCC へのアクセスを提供しますが、esp代わりに x86 バージョン - レジスタを使用しrspます。コードを変更する必要があります(非移植性)。

于 2013-09-04T23:17:15.270 に答える