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中定义。该程序编译没有错误&amp;警告。执行时,程序会定期结束,在cout
上留下以下内容:
0123456789
!123456789
您对此计划的有效性和行为有何评论?详细解释。
我认为f函数是以某种方式非法访问内存,可能是因为s在内存之前是正确的,所以带有索引的东西发生......但我真的不确定,因为我猜{{ 1}}也会以某种方式改变事物..
答案 0 :(得分:1)
我想f
的代码是:
void f(char* arr, int len)
{
arr[len + 2] = '!';
}
超过s
的长度并进入存储a
的内存,在第一个位置写!
。至少在Windows上运行。
答案 1 :(得分:1)
依赖编译器。使用gcc-4.3.4
,如果您可以将f
定义为:
void f(char* s,int n) { s[-n] = '!' ; } //danger!
生成您已发布的输出。这是在线演示:http://ideone.com/8YT7k
但是被警告这样的编码真的坏了,你不应该这样编码,因为实际的行为取决于编译器,它的版本,设置和选项。
静态数组是否彼此靠近取决于编译器,并且您的程序不应该假设。然而,在这种情况下,它们被放置在相邻的位置,但是它似乎取决于其他因素。例如,如果我在代码末尾打印s
和a
的地址,而不从代码中删除任何内容,则s
的地址高于a
,但如果我删除了您的代码,则a
的地址高于s
。看看自己:
s
的地址高于a
)a
的地址高于s
)第一个打印:
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!]
所以这取决于编译器放置静态数组的情绪!