静态字符数组&指针记忆

时间:2012-09-08 13:34:36

标签: c++ arrays static

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}}也会以某种方式改变事物..

2 个答案:

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

但是被警告这样的编码真的坏了,你不应该这样编码,因为实际的行为取决于编译器,它的版本,设置和选项。

静态数组是否彼此靠近取决于编译器,并且您的程序不应该假设。然而,在这种情况下,它们被放置在相邻的位置,但是它似乎取决于其他因素。例如,如果我在代码末尾打印sa的地址,而不从代码中删除任何内容,则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!]

所以这取决于编译器放置静态数组的情绪!