windows下栈是从高地址到低地址分配内存的,数组的分配是当作单个变量来分配内存的
成都创新互联主要从事网站设计、成都网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务闻喜,10多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
你可以再定义一个变量试试
#includeiostream.h
#includestring.h
void getmemory(const char ** p)
{
*p = new char[20];
}
int main()
{
char *str=NULL;
getmemory(str);
strcpy(str,"qew");
return 0;
}
说明为什么会让str获取到p开辟的空间。
那么void getmemory(const char ** p)这个函数形参是什么!形参实际上是p,p是调用函数的一份拷贝,p改变了调用的实参是不会改变的(你的程序的错误)。当我改变的是*p时,因为p是一份指针拷贝,p与实参指针str保存同一块地址,当改变*p时对应的实参指针str指向的内容也就改变了。
仿佛
int a = 5;
int b = a;
b = 3;
cout a;//a依然是5,因为b是a的一份拷贝,b变了,a不会变
int a = 5;
int *p = a;
*p = 3;
cout a;//a为3,因为p中存的是a的地址,当改变p指向的内容时,实际上就是改变a的内容
1 为什么你觉得会覆盖test0的内存呢?
2 一般情况下,栈是从上(高地址)往下增长的,如果你想弄明白栈的分配情况,先学会汇编,
再写个简单的程序,调试查看生成的汇编码,你应该知道怎么看吧,看完就什么都明白了;
3 test0不会在栈上分配5个字节,你认为会分5个字节是不是觉得“1111”这个玩意儿占用5个
字节呢,这里在栈上分配的是char *变量,占4个字节,你可以去了解一下常量的存放问题;
4 局部变量没有你所谓的”依次压进栈“一说,这个词是针对函数参数入栈说的;
5 局部变量在栈上的位置及对齐方式是编译器说了算,一般没人会去关心这些东西,
关心按几个字节对齐问题最多的还是在使用结构体的时候,序列化啊反序列化啊什么的;
6 关于ARM,太久不用了,不敢多说;7 感觉你知道点儿东西,也想去多知道点儿,但从上面看,你基础不扎实,有点儿乱来;
我是这么理解的,函数调用返回值也会根据类型分配一段内存空间,fun1的返回值类型是int型,程序会分配4个字节用于保存int型的返回值,而a是个整形,它的值在内存释放前赋值拷贝给了返回区空间。
fun2和fun3的返回值类型是char *,程序会分配4个字节的内存空间保存返回值,这个值存储的是一个地址,而 p = “abcde”指向的是常量区,在函数调用结束前将p指向的地址(假如是0X00000111)拷贝给了返回值区间,函数调用结束后虽然释放了局部变量p所占的空间,但函数返回值空间保存的是拷贝过来的地址(依然是0X00000111),而这个地址所指向的内存区并没有释放,所有p可以看到指向的是"abcde"
而fun3拷贝的是局部变量str所存储的地址(假如是0x00002222),函数调用结束时会释放局部变量str的分配的内存,这个时候0x00002222所指向的内容就不确定了,因为它被回收了...所有如果调用fun3,它的返回值是不确定的
空间是挨着的,但是在电脑上默认是要做4字节对齐的,也就是说你分配char[7],实际是保留了8个字节.
如果一定要挨着,在VC中可以这样
#pragma pack(1)
char a [1];
char b[5];
#pragma pack()
这样的话就是挨着的
还有一点,char *test0 =“1111”;这个是定义一个指针变量占4字节,指向的文字在不可修改的数据段,栈上只是个指针型变量.
1、每个函数被调用时都会开栈空间. 但在recursive的情况下, 同一个函数会开许多个栈空间.
就算没有recursive, 每次被调用所开的栈空间通常不会一样.栈空间中存放return address, parameter, local variable, return value.执行期对local variable取址就一定落在栈空间之内.各个函数都印parameter及local variable的地址. 多实验几次就可以推测出大概的范围。
2、栈,可以看作是一摞卡片,最上面的卡片表示程序的当前作用域,这往往就是当前正在执行的函数。当前函数中声明的所有变量都置于栈顶帧中,即占用栈顶帧的内存,这就相当于一摞卡片中最上面的一张卡片。如果当前函数调用了另一个函数,举例来说,当前函数foo()调用了另一个函数bar(),就会在这摞卡片上再加一个新的卡片,这样bar()就有了自己的栈帧(stack frame)以供使用。从foo()传递到bar()的所有参数都会从foo()栈帧复制到bar()栈帧中。(注:栈帧很有意义,因为栈帧可以为每个函数提供一个独立的内存工作区。如果一个变量是在foo()栈帧中声明的,那么调用bar()函数不会对它带来改变,除非你专门要求修改这个变量。另外,foo()函数运行结束时,栈帧即消失,该函数中声明的所有变量都不会再占用内存了。)