一方の変数のアドレスを取得しても問題がなく、もう一方の変数が0xDを取得し、無効なアドレス(の0xD)に値を書き込んだためにクラッシュする理由がわかりませんr.thefn(0);
。
これは、類似したアドレスを持たない2つの変数を示す出力です。これがGDBが示したものとアセンブリ出力です。私のx86アセンブリは素晴らしいものではありません(私はx86アセンブリを書いたことがありません)。十分な情報が表示されているかどうかはわかりませんが、表示されていない場合は、これをデバッグするために他に何が必要か教えていただけますか?1つの変数が0xBF8BAF1Cで、もう1つの変数が0xDであるのはなぜですか?C ++とアセンブリコードは以下のとおりですが、上記の要点リンクでより適切にフォーマットされています。
非自明なコンストラクターがないことを意味するPODstatic_assert
である強制文字列があります。C++が生成するデフォルトのコンストラクターを使用しています。また、スタック上にあるため、過負荷になっても影響はありません。オーバーロードされていませんが、関数が呼び出された最初の2回は正しく見えます。new
&
r
アドレスに何が影響する可能性がありますか?変数varme
のアドレスは、2回目と3回目は同じですが、3回目r
は魔法のように異なります。
これは、Visual C ++(2012は動作)、g ++ 4.6.2を使用して正しくコンパイルおよび実行され、g ++ 3.7、3.6.3、およびClang 3.0を使用するLinux(Ubuntu )では失敗します。
sanity check 1 0xbf8bb4cc
sanity check 2 0xbf8bb4cc 0xbf8bb538
sanity check 3 0xbf8bb4cc 0xbf8bb538
this 0xbf8bb538
sanity check 1 0xbf8baf1c
sanity check 2 0xbf8baf1c 0xbf8baf40
sanity check 3 0xbf8baf1c 0xbf8baf40
this 0xbf8baf40
sanity check 1 0xbf8baf1c
sanity check 2 0xbf8baf1c 0xd
sanity check 3 0xbf8baf1c 0xd
this 0xd
コードは次のとおりです。もう1つの注意点は、static_assert
デフォルト以外のコンストラクターがないことを意味するPODであることを強制するonStringがあります。オペレーター&
がオーバーロードされていないことを確認しました。
static int aa=0;
aa++;
int varme;
printf("sanity check 1 %p\n", &varme);
String r;
printf("sanity check 2 %p %p\n", &varme, &r);
//auto v=anotherfn(sz);
printf("sanity check 3 %p %p\n", &varme, &r);
//printf("callingfn=%s,%d %p %p\n", sz,aa, v, &r);
r.thefn(0);
return r;
¦0x8084101 <callingfn(char const*)+1> mov %esp,%ebp ¦
¦0x8084103 <callingfn(char const*)+3> push %esi ¦
¦0x8084104 <callingfn(char const*)+4> sub $0x34,%esp ¦
¦0x8084107 <callingfn(char const*)+7> mov 0xc(%ebp),%eax ¦
¦0x808410a <callingfn(char const*)+10> mov 0x8(%ebp),%ecx ¦
¦0x808410d <callingfn(char const*)+13> mov %eax,-0x8(%ebp) ¦
¦0x8084110 <callingfn(char const*)+16> mov 0x81bc894,%eax ¦
¦0x8084115 <callingfn(char const*)+21> lea 0x1(%eax),%eax ¦
¦0x8084118 <callingfn(char const*)+24> mov %eax,0x81bc894 ¦
¦0x808411d <callingfn(char const*)+29> lea -0xc(%ebp),%eax ¦
¦0x8084120 <callingfn(char const*)+32> mov %esp,%edx ¦
¦0x8084122 <callingfn(char const*)+34> mov %eax,0x4(%edx) ¦
¦0x8084125 <callingfn(char const*)+37> movl $0x812ee78,(%edx) ¦
¦0x808412b <callingfn(char const*)+43> mov %ecx,-0x10(%ebp) ¦
¦0x808412e <callingfn(char const*)+46> mov %eax,-0x14(%ebp) ¦
¦0x8084131 <callingfn(char const*)+49> call 0x8049a90 <printf@plt> ¦
¦0x8084136 <callingfn(char const*)+54> mov %esp,%ecx ¦
¦0x8084138 <callingfn(char const*)+56> mov -0x10(%ebp),%edx ¦
¦0x808413b <callingfn(char const*)+59> mov %edx,0x8(%ecx) ¦
¦0x808413e <callingfn(char const*)+62> mov -0x14(%ebp),%esi ¦
¦0x8084141 <callingfn(char const*)+65> mov %esi,0x4(%ecx) ¦
¦0x8084144 <callingfn(char const*)+68> movl $0x812ee8b,(%ecx) ¦
¦0x808414a <callingfn(char const*)+74> mov %eax,-0x18(%ebp) ¦
¦0x808414d <callingfn(char const*)+77> call 0x8049a90 <printf@plt> ¦
¦0x8084152 <callingfn(char const*)+82> mov %esp,%ecx ¦
¦0x8084154 <callingfn(char const*)+84> mov -0x10(%ebp),%edx ¦
¦0x8084157 <callingfn(char const*)+87> mov %edx,0x8(%ecx) ¦
¦0x808415a <callingfn(char const*)+90> mov -0x14(%ebp),%esi ¦
¦0x808415d <callingfn(char const*)+93> mov %esi,0x4(%ecx) ¦
¦0x8084160 <callingfn(char const*)+96> movl $0x812eea1,(%ecx) ¦
¦0x8084166 <callingfn(char const*)+102> mov %eax,-0x1c(%ebp) ¦
¦0x8084169 <callingfn(char const*)+105> call 0x8049a90 <printf@plt> ¦
¦
¦0x8084169 <callingfn(char const*)+105> call 0x8049a90 <printf@plt> ¦
¦0x808416e <callingfn(char const*)+110> mov %esp,%ecx ¦
¦0x8084170 <callingfn(char const*)+112> mov -0x10(%ebp),%edx ¦
¦0x8084173 <callingfn(char const*)+115> mov %edx,(%ecx) ¦
¦0x8084175 <callingfn(char const*)+117> movl $0x0,0x4(%ecx) ¦
¦0x808417c <callingfn(char const*)+124> mov %eax,-0x20(%ebp) ¦
¦0x808417f <callingfn(char const*)+127> call 0x8056d00 <SomeClass<blah>::thefn(blah*)> ¦
>¦0x8084184 <callingfn(char const*)+132> add $0x34,%esp ¦
¦0x8084187 <callingfn(char const*)+135> pop %esi ¦
¦0x8084188 <callingfn(char const*)+136> pop %ebp ¦
¦0x8084189 <callingfn(char const*)+137> ret $0x4 ¦
¦0x808418c nopl 0x0(%eax)