一個很有意思的現象,對於上面這段代碼,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]