まず、私は 2 か月前に C/C++ のプログラミングを始めたばかりなので (ただし、Java の経験は豊富です)、C/C++ の経験はまったくありません。私は論文に取り組んでおり、その目的のために以前の研究のために書かれた他のコードを使用/拡張しています。
さて、このエラーは間違いなく私が今まで遭遇した中で最も奇妙なものであり、再現できる最も基本的な形式を見つけて絞り込むのにほぼ3時間かかりました..最後に、次のコードを含むこれら2つのファイルがあります
c.hh:
#ifndef C_HH_
#define C_HH_
class complex {
public:
double re;
};
#endif
test.cc:
#include <iostream>
#include "c.hh"
int main(int argc, char **argv) {
complex* c;
c->re = 0.0;
for (int i = 0; i < 3; ++i) {
c->re = (c->re) + (i==1)?0:1;
}
std::cout << c->re;
}
私が取り出すことができる唯一の行は、c.re の初期化、つまり "c->re = 0.0;" です。ただし、コードの下部を削除しても、c.reが初期化されていないため(またはそう思いますか?)、この行がないとエラーが発生するため、これを残しました。
エラーを再現するために必要であることがわかった他のすべてのもの、つまり
1) for ループ。i=1,2,3の行を分けて書いてもエラーにはなりません。
2) i! の限界 たとえば、i が 0 から 2 までしか実行されない場合、エラーは発生しません。少なくとも 3 回の反復後にのみ発生します。
3) 明示的な代入 "c->re = (c->re) +" では、"= (c->re) +" の代わりに "+=" を使用してもエラーは発生しません。
4) i "(i==1)?0:1" の評価および (!) 条件チェック。これを行うために if(..) を使用してもエラーが発生しますが、 i が使用されていない場合、または条件チェックが実行されていない場合はエラーは発生しません。
5) c.re.の出力 つまり、「std::cout << c->re;」です。c.re ("c->re;") を評価するだけではエラーにはなりません。また、c.re をまったく評価せずに出力だけがある場合でも、エラーは発生しません。「fprintf(stdout, "%d", c->-re);」で同じことを行う エラーの原因にもなります。
また、非常に重要なのは、次のようなコードをコンパイルした場合にのみエラーが発生することです。
g++ -O3 -c -o test.o test.cc
g++ -O3 -o test test.o c.hh
「-O3」を省略してもエラーにはならないので、これがコードが理解できないエラーを生成する本当の理由だと思います。-O3 が使用されていることに注意してください。前述したように、このコードは、このような関数が何百万回も呼び出される可能性がある研究用に書かれているため、可能な限り最適化することをお勧めします。しかし、私は与えられたものからこの「慣習」を採用しただけであり、詳細や、それを使用した場合の結果が正確にどうなるかはわかりません。
その上、エラーが発生するたびに、プログラムはまったく実行されません。つまり、コードの最初の行であっても、任意の形式の出力をどこに置いても、「テスト」を実行するとすぐにエラーが発生し、何も出力されません。
最後に、プログラム「テスト」を実行しようとしたときに発生するエラーは次のとおりです。
0 [main] test 10720 cygwin_exception::open_stackdumpfile: Dumping stack trace to test.exe.stackdump
スタックダンプ ファイルには次のものが含まれます。
Exception: STATUS_ACCESS_VIOLATION at eip=00401770
eax=00000001 ebx=0028CC8C ecx=8001801F edx=00000000 esi=0028CCA0 edi=0028CCA4
ebp=0028CC68 esp=0028CC50 program=D:\somepath\test\src\test.exe, pid 13768, thread main
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0028CC68 00401770 (00000001, 0028CC8C, 800280E8, 61007D35)
0028CD28 61007D9A (00000000, 0028CD84, 61006DC0, 00000000)
End of stack trace
あなたが言うことができるように、私はこの問題で非常に迷っており、何が起こっているのかわからない. この非常に単純なコードで間違っていることはありますか? -O3 最適化を除外せずにこの問題を「修正」する方法はありますか? それとも、それほど重要ではないのでしょうか?
十分な情報を提供できたと思います。助けてくれてありがとう!