0

C++ プログラムは、main.cpp と f.cpp の 2 つの .cpp ファイルで構成されます。main.cpp ファイルのコードは次のとおりです。

//main.cpp
#include <iostream>
using namespace std;

void f(char* s,int n);

const int N=10;
static char s[N];
static char a[N];

int main ()
{
    int i;  
    for (i=0; i<N; i++)
        a[i]='0'+i;

    for (i=0; i<N; i++)
        cout<<a[i]; 
    cout<<'\n';

    f(s,N);

    for (i=0; i<N; i++)
        cout<<a[i]; 

    cout<<'\n';
}

この関数fは、ファイル f.cpp で定義されています。プログラムはエラーと警告なしでコンパイルされます。実行すると、プログラムは定期的に終了し、次のものが残りますcout

0123456789
!123456789

このプログラムの有効性と動作について、あなたのコメントは何ですか? 詳細に説明します。

おそらく、メモリ内で s が a の直前にあるため、 f 関数が a のメモリに不正にアクセスしていると思います。そのため、インデックスで何かが発生しますstatic

4

2 に答える 2

1

コンパイラによって異なります。gcc-4.3.4、次のように定義できる場合f

void f(char* s,int n) { s[-n] = '!' ; } //danger!

あなたが投稿したその出力を生成します。これがオンラインデモです:http://ideone.com/8YT7k

ただし、そのようなコーディングは本当に悪いことであり、実際の動作はコンパイラ、そのバージョン、設定、およびオプションに依存するため、そのようにコーディングするべきではないことに注意してください。

静的配列が互いに近くに配置されるかどうかはコンパイラーに依存し、プログラムはそれを想定するべきではありません。ただし、この場合は隣接して配置されますが、他の要因によるようです。たとえば、コードから何も削除せずにコードのアドレスsa末尾を印刷すると、sはより高いアドレスになりますがa、コードを削除した場合は、aよりも高いアドレスになりsます。自分を見てください:

最初のものは印刷します:

0x804a0df   //address of s
0x804a0d5   //address of a
0xa         //difference of s and a i.e (s-a)

しかし、2番目のものはこれを印刷します:

0x804a0d5   //address of s
0x804a0df   //address of a
0xa         //difference of a and s i.e (a-s) [reversed!]

したがって、静的配列を配置するコンパイラのムードに依存します。

于 2012-09-08T13:48:46.850 に答える
1

fのコードは次のとおりだと思います。

void f(char* arr, int len)
{
    arr[len + 2] = '!';
}

の長さを超えて、が格納さsれているメモリに移動し、最初の位置にaa を書き込みます。!少なくとも Windows で動作します。

于 2012-09-08T13:45:27.583 に答える