c中定义变量的内存分配顺序问题(极易错!!!)
来源:互联网 发布:史丹利快报的淘宝店 编辑:程序博客网 时间:2024/04/20 10:36
对于c语言中大家都知道所有的变量都必须是先定义后使用的,但是但是,对于好多人而言,基本上没有人(不管是老手还是菜鸟)来注意自己的编译器和操作系统对这个东西是如何处理的,
1,如果全是一样的类型,比如全是int(char,double,float),编译器会如何分配呢??是从大到小还是从小到大,,
2, 数组的分配方式和基本类型一样吗??编译器又是如何处理的??
3, 如果是基本类型和数组混合呢??
4,倘使是不同的操作系统呢,??它又有什么不同呢??
好了,接下来,我们大家一起看一看吧!!
(注意:下面我们的程序都是在:dev-C++ 5.11, win7,32位的系统下运行的结果)
1.全是一样的类型
#include<stdio.h>#include<conio.h>int main(){int a;int b;int c;printf("a is ip:%p\n", &a);printf("b is ip:%p\n", &b);printf("c is ip:%p\n", &c);printf("nihao, mingtian");getch();return 0;}
好,接下来我们看一看结果!
由图可知,我们的编译器和系统给它们分配的时候是,先找了一块空闲区,确定了之后,然后将高地址给了第一个定义的变量,将次高地址给了第二个变量,其他依次类推,可以得出,我们的地址分配是从高到底的!!
下面这个是全是char类型时候的分配情况,所以说我们上面的总结是正确的!
当然我相信,就是全部换成float,double也是一样得
2, 数组的话
#include<stdio.h>#include<conio.h>int main(){char a[3];printf("a[0]'s is ip:%p\n", &a);printf("a[0] is ip:%p\n", &a[0]);printf("a[1] is ip:%p\n", &a[1]);printf("a[2] is ip:%p\n", &a[2]);printf("a[3] is ip:%p\n", &a[3]);printf("nihao, mingtian");getch();return 0;}
可以看到结果:
大家可以很清楚的看到,我们的编译器和操作系统对其的分配方式
还是同样的道理,先找空闲区,然后将数组里的第一个元素分到了底地址处,将第二个分配到了次底地址处,后面的同理,所以我们可以总结一下:对于数组,分配方式是从低到高,跟基本类型的分配方式不一样,
此时,我们大家再来看一个例子:
#include<stdio.h>#include<conio.h>int main(){char a[3];char b[2];printf("a[0]'s is ip:%p\n", &a);printf("a[0] is ip:%p\n", &a[0]);printf("a[1] is ip:%p\n", &a[1]);printf("a[2] is ip:%p\n", &a[2]);printf("a[3] is ip:%p\n\n\n", &a[3]);printf("b[0] is ip:%p\n", &b[0]);printf("b[1] is ip:%p\n", &b[1]);printf("b[2] is ip:%p\n", &b[2]);printf("nihao, mingtian");getch();return 0;}
请大家务必牢记:这里经常被好多人不重视:
现在我们也能清晰的看到:对于两个数组,我们可以将其看作两个基本类型,他们的内存分配遵从从高到低,所以我们可以看到a[0]的地址比b[0]高,
然后他们具体的位置取决于自己数组的大小,也就是说对于先定义a数组,然后再定义b数组的情况,现将整个a数组放在了高地址,将整个b数组放在了相对的次高地址
然后,具体对数组内部的东西进行分配处理,内部其实也就是我们上面说的分配从低到高
大家可能会很有疑惑为什么a[0],b[2]的地址是一样的??
大家不妨自己想一想,其实也很简单:
先定义a数组,整体放在了高地址处,而对于数组内部a[0]放在了相应的底地址处(0022febd)
而对于数组b,整体放在了底地址处,同理数组内部b[2]也就放在了相对于b[0](0022febb)处的高位,也就是(0022febd)
但是,但是,但是,大家一定要清楚,此时我们的是C,所以我们的编译器此时是对b[2]是不分配的内存的,如果我们非要取出东西或探究地址,那也只能在b[1]地址(0022febc)的相对下一个,也就是a[0]的地址了
哈哈,很简单吧!!
3:混合(基本类型和数组)
#include<stdio.h>#include<conio.h>int main(){int a;char b[2];int c;printf("a is ip :%p \n", &a);printf("b[0] is ip:%p\n", &b[0]);printf("b[1] is ip:%p\n", &b[1]);printf("b[2] is ip:%p\n", &b[2]);printf("c is ip :%p\n", &c);printf("nihao, mingtian");getch();return 0;}
运行结果如下:
同样的:我们分析还是将数组当做基本类型对待
所以a变量在内存地址最高位,b数组在内存地址次高位,c其次,
当a确定了位置(0022febc)后,也就确定了b[0](0022feba),因为数组是从低到高,b[1]是(0022febb),b[2]是(0022febc)(注意b[2]应该不存在,也就是没有为其分配内存,所以也就是b[1]的位置相对下一个,也就是a的地址处),同理也就确定了C的地址(0022feb4)
至于为什么是b4,而不是b9,大家如果有兴趣的话可以看看我的另外一篇博客
关于内存结构体共用体在linux/window下的分配情况:
点击打开链接:http://blog.csdn.net/msdnwolaile/article/details/50158463
好好,接下来我们来看看linux下是如何做的:
我们也可以很清楚的看到,里面的三个变量的类型是一样的,都是int
结果如下:
同样的,大家可以看到,变量a先定义,但是a的地址还低(0x7ffc4fb9c134)
然后定义变量b,b的地址比a要高一点(0x7ffc4fb9c138)
然后依次c,地址为(0x7ffc4fb9c13c)
所以,我们可以同样总结,在linux(我的是ubuntu kylin 14.04)下,一般来说,对于基本变量的分配是从低地址到高地址的
当然不管是window还是linux下,
定义 : int a, b, c;
int a;
int b;
int c;
上面两个都是一样的!!!!分配方式是并不影响的
2, linux下的数组
可以看到上面是对数组的检验:
结果如下:
好啦,我们可以分析结果,首先根据a[0],a[1],a[2]的地址的大小,知道对于数组也是如window,是从低到高的
而如果我们将两个数组都当做基本类型
大家注意,这里可就跟上面不一样了,从高到低的,
哈哈,这回大家明白了吧!!
- c中定义变量的内存分配顺序问题
- c中定义变量的内存分配顺序问题(极易错!!!)
- linux定义变量内存地址分配顺序
- c++中变量的内存分配问题
- C\C++编译器关于变量的内存分配顺序总结
- C\C++编译器关于变量的内存分配顺序总结
- C\C++编译器关于变量的内存分配顺序总结
- C变量定义内存分配机制
- C变量定义和内存分配机制
- C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?
- C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?
- C/C++中结构体变量及指向结构体指针变量的内存分配问题
- c中内存分配&变量的存储类别
- c中变量定义问题
- java中有关“变量”内存分配问题
- C --- 变量内存分配
- 数据结构 学习笔记之:结构体及其所定义变量的内存分配的问题
- 关于构造函数析构函数以及成员变量内存分配顺序的一些问题
- 迪杰斯特拉算法C++实现
- Python-装饰器以及对带有参数的装饰器的理解
- AFNetworking 原作者都无法解决的问题: 如何使用ip直接访问https网站?
- Codeforces 617C Watering Flowers 【暴力 数据范围】
- Java 包
- c中定义变量的内存分配顺序问题(极易错!!!)
- Codeforces 617A Elephant
- Codeforces 617B Chocolate
- Codeforces D Polyline
- C++链表
- HDOJ 5611 Baby Ming and phone number
- 咱码农为啥会(珍爱生命)远离企业应用开发
- HDOJ 5610 Baby Ming and Weight lifting
- UVa 489 Hangman Judge