2017-01-27 6 views
1

thisのようなものを実装したいと思います。ネイティブメモリはJavaヒープに割り当てられます。これが機能するためには、私はこのコードの一部が動作する必要があります:私がやろうとしていることである新規/削除割り当てをグローバルに埋め込む方法はありますか?

const static int pad = 16; 
void * operator new(size_t t) throw(std::bad_alloc) { 
    void* padded = malloc((int) t + pad); 
    void* p = static_cast<void *>(static_cast<char *>(padded) + pad); 
    std::cout << "new: " << p << " padded " << padded << " size: " << t << std::endl; 
    return p; 
} 

void operator delete(void *p) throw() { 
    if (p != 0) { 
    void *padded = static_cast<void *>(static_cast<char *>(p) - pad); 
    std::cout << "del: " << p << " padded " << padded << std::endl; 
    free(padded); 
    } else { 
    std::cout << "pointer is zero!" << std::endl; 
} 
} 

は、すべてのメモリ割り当てにいくつかのバイトを追加します。これは、(ほとんどの削除が成功している)[OK]を動作しているようですが、私はエラーを取得しています:

java(379,0x700002206000) malloc: *** error for object 0x7fc104122180: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 
スタックトレースが freeこの回線から(すなわち、ない私の delete)すぐに呼ばれたことが示され

name = temp.str(); 
namestring

、そしてtempstringstreamです。私はJNI以外のコンテキストでこのエラーを再現しようとしましたが、そこではクラッシュしませんでした。

私はこのようなメモリを水増ししていた場合は、明らかにそれはnewを介して、またはmallocから直接割り当てられていたdelete何かに割り当てられていたfree何かに間違っているだろう。それも可能ですか?アドレスが正常に割り当てられ、その後、割り当て解除されたように見える

new: 0x7fc104122190 padded 0x7fc104122180 size: 32 
del: 0x7fc104122190 padded 0x7fc104122180 
new: 0x7fc104122180 padded 0x7fc104122170 size: 32 

私の標準出力にエラーのアドレスを検索すると、これをサポートしています。同じアドレスが、stdoutに最後の行に印字されていないアドレスとして再度表示されました(私は、このアドレスが2番目の割り振りで未アドレスアドレスになったのは偶然と思います)。しかし、これは最後の行であるstdに出力されているので、freeへの失敗した試みは私が見ているコードを通らない(たとえ私がfreeをオーバーライドしたとしても)。

このアプローチを有効にすることはできますか?または、自分自身を完全に管理しているオブジェクトに私のnew/deleteの範囲を絞り込む必要がありますか?

+1

注意: 'operator new'または' operator delete'の内部からのC++ストリームを使用すると問題に遭遇する可能性があります。ストリーム操作で 'new'と' delete'が使用されることがあります。それが起こると、すべてがクラッシュします。 C I/Oは 'new'と' delete'について何も知らないので大丈夫です。 –

+0

@ RawN:これはかなり無関係です。「演算子new」をオーバーロードする考え方全体は、非標準のメモリソースからメモリを割り当てることです。 「Javaヒープ」は、もっともらしいソースのように聞こえます。 – MSalters

+0

@PeteBecker、私は私の叫び線をコメントしても問題が発生します。 – amos

答えて

0

new()およびdelete()の他に、new[]()およびdelete[]()の演算子があります。たとえば、new()[]演算子を使用して配列を割り当てた後、delete()を使用して割り付けを解除すると、標準ライブラリにいくつかの矛盾があります。 4人のオペレータすべてに過負荷をかけていないと、これらの不一致によりメモリ割り当てエラーが発生する可能性があります。 C++ 17ではさらに新しい/削除演算子になることに注意してください。

+0

私のソースコードでこの種の矛盾はありませんが、サードパーティのライブラリがこれをしないことを保証することはできません。コンパイラはそれを紹介するだろうか? – amos

関連する問題