2009-03-18 4 views
1

奇妙なエラーが発生しました。MSVC 2005でCコードを実行中に奇妙なエラーが発生しました

すべてのCコードのMSVS2005にワークスペースがあります。私は1つのCファイルにグローバル変数を宣言しています(file1.c)。このファイルにはmain()という関数があり、その変数の値を初期化します。他のCファイル(file2.c)。 mainから、このグローバル変数の値を1に設定する関数(file2.cのfunc1)への関数呼び出しがあります.file2.cでは、グローバル変数を "extern .."と宣言してアクセスしました。しかし、私が気づいたのは、コード実行が関数func2を入力するメイン関数の瞬間に、グローバル変数のアドレス自体が完全に異なるアドレスに変更されていることがウォッチウィンドウに表示されていることです(ウォッチウィンドウで私は&変数を見ています) 。結果として、その変数の値が1に設定されると、値1を全く異なるメモリアドレス自体に書き込む。だから、後でこの変数を使ってif条件(変数== 1の場合)をチェックすると、それは0の値を示し、if条件を満たしておらず、そのコードパスを取っていないそのパス。

回避方法: 私はその変数を私の既存のグローバル構造の1つに宣言し、同じ操作を行うためにこの変数にアクセスしました。コードは期待どおりに動作します。

グローバル変数のアドレスがCファイルでグローバルとして宣言されている場合、そのグローバル変数のアドレスが変更される原因となるエラーの説明は何ですか?どの* .cファイルを宣言しても、 "extern"を使ってどのファイルにアクセスするかは関係ありません。結果は同じグローバル変数アドレス変更とそれに続く誤動作です。最適化オプションは有効になっていません。

おかげで、

〜AD

+0

些細なエラーがあります。いくつかのコードスニペットを巻いてください。 – sharptooth

+0

コードを記述するのではなく、重要な部分を直接ここに挿入すると、あなたの質問がはるかに読みやすくなります。 – schnaader

答えて

0

は、多分それは揮発性宣言してみてください(つまり、グローバルのためにも有効かどうかわからない)、それは何とかトリッキーなってきた場合に、任意のコンパイラの最適化を無効にします。

0

異なる変数が異なる翻訳単位で異なるアドレスを持つ場合、同じ名前の変数が2つ以上表示されていません。

最も一般的な原因:誤って同じ名前のスタック上にローカル変数が宣言されている可能性があります。これについてコードを確認してください。変数が本当にグローバルである場合、2つの翻訳単位に同じシンボルが含まれていると、リンカーは文句を言います。

これは役に立ちませんが、同じシンボル名のコピーが複数表示されている場合は、マップファイルを参照することをお勧めします(リンカ設定で有効にすることができます)。

すべての外部シンボルは、その名前、アドレス、および(あなたのケースでは最も重要な)オブジェクトファイルを含むオブジェクトファイルとともにリストされています。

マップファイル内のアドレスは、単なるオフセットでも構いません。この場合、すべての計算は、一度しか存在しないことが知られているシンボルに関連して行います。 main()エントリポイントがこれに適しているかもしれません。

0

おそらくタイプミスやコード内の何かが似ています。

FILE1.C

int variable; 
void fun1(int k); 

int main() 
{ 
    printf("%d\n", variable); 
    fun1(4); 
    printf("%d\n", variable); 
} 

FILE2:この作業のデモを試してみてください。C

extern int variable; 

void fun1(int k) 
{ 
    variable = k; 
} 

出力:

0 
4 

コンパイルする:

cl.exe file1.c file2.c 
1

が唯一実際にコードを見ることなく推測することはできますが、ここでは2つの可能性あり:

  1. グローバルに変数がいずれかのローカルに隠されているmain()またはfunc2()(またはおそらくfunc1() - 質問にはfunc1()が記載されていますが、これは誤字文字だと思われます。これがコードをカット&ペーストすることが非常に重要な理由です)。
  2. file1.cのグローバル変数をstaticと誤って宣言していて、file2.cのextern宣言にイニシャライザがあります。 extern宣言でイニシャライザを使用すると、その宣言も定義になります。
関連する問題