2016-03-25 16 views
0

私のプログラムでは私はガベージコレクタを持っていて、プログラム中のローカル変数に保持されているオブジェクトを追跡して、ガベージコレクションが生きている間にそれらを収集しないようにする必要があります。スタックの例外処理とデストラクタの巻き戻し。情報の使い方

私は複合型を作成するリンクリストを使用していましたが、C++言語では、特に例外処理に関連したデストラクタの目的のために、そのリンクリストを保持する必要があります。

私はC++例外ハンドラによって保持された情報を使用してコードを単純化することを考えています。それを行うポータブルな方法はありますか?

少なくとも、g ++とclangに関する情報はありませんか?

私はマルチタスクを使用していますが、ガベージコレクタの実行時にはすべてのタスクで実行できるはずです。

私が正確に必要とするのは、デストラクタが設定されている(そして非破壊的な方法で)ローカル変数をトラバースすることです。

+0

「私のプログラムではガベージコレクタがあります」 - 停止します。これはすでにエラーです。 C++はガベージコレクションを不要にするRAIIを使用しています。 JavaとC#はガベージコレクションを持っていますが、それもエラーです。しかし、それを修正するにはあまりにも遠すぎます。 –

答えて

0

これはデストラクタのためのものです。ヒープ上であろうとスタック上であろうとオブジェクトがスコープから外れたときを知る必要があるならば、デストラクタを使用します。

+0

すでに述べたように、私は既にリンクリストとデストラクタが付加された複合オブジェクトを使用しています。問題は、C++例外処理コードによって何らかの形で同じ情報が既に保持されていることです。ですから、私はその情報を、効率の低下、複合体の代わりに単純な型としてオブジェクトを宣言し、単純化するという事実に関連するエラーを避けるために使用したいと思います。 –

+0

C++例外処理コードは、この情報を使用してオブジェクトを破棄し、デストラクタを呼び出します。典型的なC++コンパイラはこれを、前のスタックフレームを指す<前のフレーム、アドレス>タプル、およびコンパイルされたデストラクタを呼び出すコードのアドレスの単一リンクリストとして実装します。これはC++では直接使用できません。この情報を使用する正しい方法は、私が書いたように、デストラクタを適切に実装することです。 –

0

gnu gccコンパイラが発行したコードを調べると、どのデストラクタが実行されるかに関する情報が、コードフォームIDで「保存」されていることが判明しました。その情報を取り戻すのは難しいです。

実装は異なる可能性があり、コードはプロセッサインスタンスのアドレスと共にデストラクタコードのアドレスをリターンアドレスとしてプロセッサスタックにプッシュしている可能性があります。

私は努力を断念する準備ができましたが、別のハッキールートが見つかりました。

私はgnuコンパイラが16バイトの境界でスタック上の構造体を整列させることに気付きました。 私の構造は8バイトなので、8未使用のバイトがあります。 だから私はスタックに割り当てられたオブジェクトを追跡するためにそれらを使用できると思った。 コンパイルフラグに応じて、-m64、-mx32などの変更や変更が必要です。

どのようにしても、私はコードをコンパイルして-m64と-mx32の両方のモードでコンパイルして動作させることができました。

純粋な "C++"(まったく逆)ではありませんが、コードが動作し、意図した効果があります。

#include <stdio.h> 

#define ONSTACK(x) (((size_t)x)&0xf0000000)==0xf0000000 
struct A; 
void* P=nullptr; 

struct A{ 
    static int i; 
    long long a; 
    A(){ 
     if(ONSTACK(this)){ 
      *(void**)(this+1)=P; 
      P=(void*)(this+1); 
     } 
     printf("this=%p\n",this); 
     a=0x1111111111111111*i;i++; 
    } 
    ~A(){ 
     if(ONSTACK(this)) 
      P=*(void**)(this+1); 
      *(void**)(this+1)=nullptr; 
     a=0xFFFFFFFFFFFFFFFF;} 
}; 

int A::i=0xA; 
void* p; 

void r1(){ 
    A x;int xx=0x66666666; 
    A y;int yy=0x77777777; 
    A z;int zz=0x88888888; 
    int b=0x2222222222222222; 
    printf("hello world %p\n",&b); 

    for(void* i=P;i!=nullptr;i=*(void**)i){ 
     printf("a=%llX\n",(((A*)i)-1)->a); 
    } 
} 

void r2(){ 
    long long r2a; 
    r2a=0x3333333333333333; 
    r1(); 
} 

A A0; 

int main(int argc, char **argv) 
{ int i;p=(char*)&i-0x100; 
    printf("sizeof(P)=%i\n",sizeof(P)); 
    r2(); 
}