#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void)
{
int fd;
int size=0,i=0;
char str1[48]={0};
char str2[16]={0};
char *p=NULL;
strncpy(str1,"Build with gcc 4.3 under Ubuntu 64bit, 2011-7-23",48);
strncpy(str2,"123456789ABCDEF",16); /* 16 bytes */
printf("%p %p %p\n",&i,str1,&str2);
p=(str1>str2?str2:str1);
for(i=0;i<sizeof(str1)+sizeof(str2);i++)
{
printf("%c",*(p+i));
}
printf("\n");
#ifdef WRITEFILE
fd = open("data.bak",O_RDWR | O_TRUNC);
size = write(fd,(str1>str2?str2:str1),sizeof(str1)+sizeof(str2));
printf("%d\n",size);
#endif
return 0;
}
一個很有意思的現象,對於上面這段代碼,Ubuntu 64bit和FreeBSD的結果是不同的。
root@ubuntu:~# ./wr
0x7fff9a648150 0x7fff9a648180
Build with gcc 4.3 under Ubuntu 64bit, 2011-7-23123456789ABCDEF
[root@freebsd ~]# ./rw
0x7fffffffec30 0x7fffffffec20
123456789ABCDEFBuild with gcc 4.3 under Ubuntu 64bit, 2011-7-23
通常意義上,函數體內部聲明的變量都會在棧上分配,地址是向下增長的,那麼就是freebsd的結果。可是Ubuntu的結果正好相反,分配地址看起來都是棧上分配的地址。
真是很奇怪的問題,難道是Ubuntu對於數組的處理採取了不同的方式?
好吧,繼續追蹤,刪掉不影響結果的代碼,最後簡化成這個樣子:
#include <stdio.h>
int main(void)
{
char str1[48]="1";
char str2[16]="2";
printf("%p %p ",str1,&str2);
str1>str2?printf("Down\n"):printf("Up\n");
return 0;
}
嗯,夠簡潔哦,親!
root@ubuntu:~# cc wr2.c;./a.out
0x7fff9f7e32e0 0x7fff9f7e3310 Up
[root@freebsd ~]# cc wr2.c;./a.out
0x7fffffffec50 0x7fffffffec40 Down
看見了么,親?就是這樣神奇!都是64位系統有沒有!結果就是不一樣,有沒有!
好吧,我再修改!
#include <stdio.h>
int main(void)
{
char str1[2]="1";
char str2[1]="2";
printf("%p %p ",str1,str2);
str1>str2?printf("Down\n"):printf("Up\n");
return 0;
}
最終發現了這樣的現象,將str1定義為1個字節,那麼地址向下增長;定義為2個字節,地址向上增長。
又做了一些測試,得出如下結論:Ubuntu下,系統會比較兩個數組變量的空間大小,優先把小的數組定義在前面。
root@ubuntu:~# gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
[root@freebsd ~]# gcc -v
Using built-in specs.
Target: amd64-undermydesk-freebsd
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070719 [FreeBSD]