0

一个 C++ 程序由两个 .cpp 文件组成,main.cpp 和 f.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

您对该程序的有效性和行为有何评论?详细解释。

我想 f 函数正在以某种方式非法访问 a 的内存,可能是因为 s 就在内存中的 a 之前,所以会发生带有索引的事情……但是,我真的不确定,因为我想static也会以某种方式改变事情……

4

2 回答 2

1

我猜的代码f是:

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

它经过长度s并进入存储的内存,在第一个位置a写入 a 。!至少在 Windows 上工作。

于 2012-09-08T13:45:27.583 回答
1

取决于编译器。,gcc-4.3.4如果您可以定义f为:

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

生成您发布的输出。这是在线演示:http: //ideone.com/8YT7k

但请注意,这样的编码真的很糟糕,你不应该这样编码,因为实际行为取决于编译器、它的版本、设置和选项。

静态数组是否彼此靠近取决于编译器,您的程序不应该这样假设。然而,在这种情况下,它们被相邻放置,但这似乎取决于其他因素。例如,如果我在代码的末尾打印 和 的地址,而不从代码中删除任何内容,则s地址高于,但如果我删除了代码,则地址高于. 看看自己:asaas

第一个打印:

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

但是第二个打印了这个:

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 回答