關於棧地址的增長方向

来源:互联网 发布:淘宝买电棍 编辑:程序博客网 时间:2024/04/30 23:25
#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]

原创粉丝点击