關於棧地址的增長方向
来源:互联网 发布:淘宝买电棍 编辑:程序博客网 时间: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]
- 關於棧地址的增長方向
- 栈的属性和buf的地址增长方向
- 栈区的地址增长方向与buf地址的增长方向是两个完全不同的概念
- 没有方向的方向
- 地址转换、内存地址扩展方向
- 如何确定栈的增长方向地址是递增还是递减
- Linux栈空间及栈地址方向
- 心的方向就是幸福的方向
- 生命的方向
- 锻炼的方向。
- 关于目前的方向
- 学习技术的方向
- 感兴趣的研究方向
- PHP的学习方向
- 开发人员的方向选择
- 我们的方向在......
- 努力的方向
- 毕业设计方向的选择
- LINUX几个强大的编辑器
- 带缺省参数的重复声明
- 综合css – 兼容性的渐变背景效果
- Learning Android 第十五章 NDK 翻译总结
- jquery.validate.js的基本用法入门
- 關於棧地址的增長方向
- .NET中弹出确认框后转向另一页面的解决方案
- 一念之差
- 好了,开始第一篇学习日志,C++ Primer 第七章 :函数
- Map.Entry类使用简介
- Spring Security3 入门一
- jQuery研究体会
- 一些有用的链接
- prime