您的位置:首页 > 编程语言 > C语言/C++

c语言堆和栈的小问题和程序在vc6和GCC下遇到的不同区别

2016-06-27 19:40 302 查看
question one

#include"stdio.h"
#include"stdlib.h"
int * getnumber()
{
int *a;
int*a=(int*)malloc(sizeof(int));
*a=100;
return a;
}
int * getnumber2()
{
int a=200;
return &a;
}
int getnumber3()
{
return 0;
}
int main()
{
int *v1=getnumber();
int *v2 =getnumber2();
//getnumber3();
printf("%d,%d",*v1,*v2) ;
}


首先,看看这结果是什么?

结果是 100,200

好的,我再将注释全部消去;

#include "stdio.h"
#include    "stdlib.h"
int * getnumber()
{
int *a;
int*a=(int*)malloc(sizeof(int));
*a=100;
return a;
}
int * getnumber2()
{
int a=200;
return &a;
}
int getnumber3()
{
return 0;
}
int main()
{
int *v1=getnumber();
int *v2 =getnumber2();
getnumber3();
printf("%d,%d",*v1,*v2) ;
}


结果又是什么呢?

结果是100 ,43984126

也就是后面的*v2 出现了一堆乱码。

这又是为什么呢?

malloc 和new 语句创建的内存空间存放在堆

局部变量存放在栈上,malloc是从堆区申请空间,函数结束后不会自动释放,如果不人为地释放的话,要等到程序结束后,系统才会自动回收

但是关键的是第一次的程序,输出是正常的

那为什么呢,如果局部变量失效了,为什么第一次可以呢

而且为什么加了GetNumber3之后就不行了~

GetNumber3看代码其实什么也没做对吧~~

返回值也没有赋值出去~

之前成功的输出了100 200

那到底是怎么影响的呢~~

要从代码中看到内存数据的变化~

程序的内存开辟区域有三类

静态存储区,堆,栈

静态变量存放在静态存储区~

malloc 和new 语句创建的内存空间存放在堆

局部变量存放在栈上

代码都是放在栈空间执行的,所以局部变量都是在栈上开辟的

GetNumber3 其实的作用就是覆盖了栈空间

在没有GetNumber3的时候,printf 执行时,获取v2时,栈空间中V2上的值还是100

比如程序的执行顺序是1 2 3 4 5 6 7 8 9 10

在3处调用了函数GetNumber2

函数返回后 那么v2指向的地址是4(值200的地址)~

此时函数回到3继续执行接下来的代码,

在printf的情况下,代码执行获取v1 和v2指向的值,此时4中的值还是200

所以输出的是100 200

如果先遇到了GetNumber3那么,GetNumber3的程序代码执行之后就覆盖了4的地址~

这时候再执行printf,获取v2指向的值的时候,就成了随机数~

其实也不是随机数,而是此时4上的值,不过已经被GetNumber3的代码段覆盖了而已!

函数保留原来的数据,也是有条件的

局部变量跨作用域是很危险的哈~

question two

#include"stdio.h"
int main()

{
int n=0;
printf("%d %d %d %d\n",n++,n++,n++,n++,n++,n++);
}


这里的输出应该是什么呢?

6 5 4 3?or 0 0 0 0;

不,结果是5 4 3 2.

#include"stdio.h"
int main()

{
int n=0;
printf("%d %d %d %d %d %d\n",n++,n++,n++,n++,n++,n++);
//printf("%d",n);
}


我们将所有的n都分别输出看看,会发现,5 4 3 2 1 0;

将注释消去,发现n是6;

也就是说

滞后自增,会在整个语句之后起到作用,在printf语句中也是一样的。

很奇怪,在vc6.0环境下,输出结果完全不同 是

0 0 0 0和6 5 4 3 2 1

Visual C++6.0用的是vc编译器,DEV-C++用的是mingw-gcc编译器。两个东西不同的。要说标准,肯定是gcc比较符合c++标准。但是要说效率,在windows平台上,gcc的效率还是比不上vc的

Visual C++6.0很多Ansi C和C++的标准都不支持,因为太老了,是96年开发的,而C语言新的标准是99年定的,因此,很多新的东西都不支持,这是第一。第二,VC6是Ms开发的,MS的编译器都比较一般;DEV-C++其内核是GNU的。

gcc执行流程 源文件→预处理→编译→汇编→链接→可执行文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编辑器 malloc sizeof