精华内容
下载资源
问答
  • 栈向下生长

    2021-03-05 08:16:38
    先定义的变量的地址在高地址,后定义的变量放在低地址,由于后定义的变量放在上面,因此这种效果称为向上生长. windows系统有8个字节的保护空间,Linux没有
    • 先定义的变量的地址在高地址,后定义的变量放在低地址,由于后定义的变量放在更低的地址,因此这种效果称为栈向下生长.

    • windows系统有8个字节的保护空间,Linux没有在这里插入图片描述

    展开全文
  • 问题一:如何判断内存中向下生长的 试验代码如下: 1 #include <stdio.h> 2 3 void func(int x, int y, int z) 4 { 5 printf("func x is %d---%p\n", x, &x); 6 printf("func y is %d...

    问题一:如何判断内存中栈是向下生长的

    试验代码如下:

     1 #include <stdio.h>
     2 
     3 void func(int x, int y, int z)
     4 {
     5     printf("func x is %d---%p\n", x, &x);
     6     printf("func y is %d---%p\n", y, &y);
     7     printf("func z is %d---%p\n", z, &z);
     8 }
     9 
    10 int main(void)
    11 {
    12     int x = 100;
    13     int y = 200;
    14     int z = 300;
    15 
    16     func(x, y, z);
    17     printf("main x is ---%p\n", &x);
    18     printf("main y is ---%p\n", &y);
    19     printf("mian z is ---%p\n", &z);
    20 
    21     return 0;
    22 }

    上述代码在VC++6.0上执行结果如下:

    可以看出在

    1)在函数内部定义的局部变量是按定义变量的先后顺序入栈的;

    2)函数参数是从后往前入栈的;   

    问题二:为什么函数参数的入栈顺序是从后往前???

    答案是:C为了支持可变长参数.

    实验代码如下:

     1 #include <stdio.h>
     2 #include <stdarg.h>
     3 
     4 int maxvalue(int n, ...)
     5 {
     6     int tmp = 0;
     7     int max = 0;
     8     int i   = 0;
     9 
    10     /*定义一个指针*/
    11     va_list paras; //char *paras;
    12     
    13     /*  根据字符串参数使指针指向第二个参数(实际的第一个参数) */
    14     va_start(paras, n);
    15     //paras = (char *)&n + sizeof(n); 
    16 
    17     while(n-- > 0)
    18     {
    19         /*读取向参数的值并使指针指向下一个参数*/
    20         tmp = va_arg(paras, int);
    21         //tmp = *(int *)(paras + (i++)*sizeof(n));  
    22         max = (max > tmp) ? max:tmp;
    23     }
    24     /*给指针清零,防止野指针*/
    25     va_end(paras);
    26     //paras = NULL;
    27     return max;
    28 }
    29 
    30 int main(void)
    31 {
    32     int max = 0;
    33 
    34     max = maxvalue(3, -21, 11, -73);
    35     printf("max is ---%d\n", max);
    36 
    37     max = maxvalue(5, 21, 11, 73, -5, 99);
    38     printf("max is ---%d\n", max);
    39 
    40     return 0;
    41 }

    只有当栈是向下生长的时候,才会根据第一个参字符串数一次读取后面参数的值,因为C是支持可变长参数的。

    编写支持可变长参数的函数时,可以使用库函数的宏,也可以不用。

     

     

     

      

     

    转载于:https://www.cnblogs.com/philospy/p/4093307.html

    展开全文
  • 的生长方向分为向上生长和向下生长。 看下图 假定有两个变量a和b,a先入栈,b后入栈。如果a的内存地址大于b的内存地址, 那么的开口向下,反之的开口向上。 看下面的代码 int a = 10; int b = 10; ...

    栈的生长方向分为向上生长和向下生长。

    看下图

    假定有两个变量a和b,a先入栈,b后入栈。如果a的内存地址大于b的内存地址,

    那么栈的开口向下,反之栈的开口向上。

    看下面的代码

    int a = 10;
    	int b = 10;
    	cout << &a << " " << &b << endl; //我这里是看口向下(debug),但release下栈看口向上生长

    那么如果在一个开口向下的栈中,数组的内存排列方式也是上面内存地址高

    下面内存地址低吗?显然不是。

    cout << array << endl;
    	cout << array + 1 << endl;

    所以我们可以得出结论,在栈中,无论开口向上还是向下,数组的内存地址都是从上往下

    增加的。

     

     

    展开全文
  • 内存生长方向

    2020-09-28 12:15:14
    :它的生长方式是向下的,是向着内存地址减小的方向增长。的开口是向下的,上面的底部是底,下面的开口是栈顶。 在内存中,“堆”和“”共用全部的自由空间,只不过各自的起始地址和增长方向不同,它们之间...

    堆栈和内存增长方向问题:

    堆:生长方向是向上的,也就是向着内存地址增加的方向。通常我们在画内存四区图时,堆的开口是向上的。

    栈:它的生长方式是向下的,是向着内存地址减小的方向增长。栈的开口是向下的,上面的底部是栈底,下面的开口是栈顶。

    在内存中,“堆”和“栈”共用全部的自由空间,只不过各自的起始地址和增长方向不同,它们之间并没有一个固定的界限,如果在运行时,“堆”和 “栈”增长到发生了相互覆盖时,称为“栈堆冲突”,系统崩溃。
     

    栈的增长方向与栈帧布局

    这个上下文里说的“栈”是函数调用栈,是以“栈帧”(stack frame)为单位的。
    每一次函数调用会在栈上分配一个新的栈帧,在这次函数调用结束时释放其空间。
    被调用函数(callee)的栈帧相对调用函数(caller)的栈帧的位置反映了栈的增长方向:如果被调用函数的栈帧比调用函数的在更低的地址,那么栈就是向下增长;反之则是向上增长。

    而在一个栈帧内,局部变量是如何分布到栈帧里的(所谓栈帧布局,stack frame layout),这完全是编译器的自由。
    至于数组元素与栈的增长方向:C与C++语言规范都规定了数组元素是分布在连续递增的地址上的。引用C语言规范的规定:

    An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.
    A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

    其实double a0[4]这个声明告诉编译器的是:我需要在栈帧里分配一块连续的空间,大小为sizeof(double)*4,并且让a0引用该空间的起始位置(最低地址);
    而不是说:我要根据栈的增长方向,先分配a0[0],然后分配a0[1],再分配a0[2],最后分配a0[3],于是如果栈是向下增长那a0[1]就应该比a0[0]在更低的地址——不是这样的。

    所以在题主给的例子里,a0和a1这两个分配在栈帧里的数组到底哪个在高地址哪个在低地址,其实并不反映栈的增长方向,而只反映了编译器自己的决定。
    C与C++语言的数组元素要分配在连续递增的地址上,也不反映栈的增长方向。

     

    展开全文
  • 的变化规则:1、方法调用会导致生长,具体包括两个步骤:一、插入方法返回地址(图中的Fn:);二、将实际参数按值(可以使用ref或out修饰)拷贝并插入到中(可以使用虚参数访问)。2、遇到局部变量定义会...
  • 对于c语言中,是向上还是向下生长,一般由操作系统决定。一般是向下生长,因为一旦是向下生长,最高地址确定之后,就不会发生溢出。但是不管是向下生长还是向上生长,buf的生长的方向都是向上的,buf是...
  • 向上生长的堆栈: Bottom对应的是堆栈的底 Top对应的是堆栈的栈顶 向下生长的堆栈:
  • 在没有MMU的时代,为了最大的利用内存空间,堆和被设计为从两端...而则对方向 不敏感,一般对的操作只有push和pop,无所谓向上向下,所以就把堆放在了低端,把放在了高端。MMU出来后就无所谓了,只不过也没必
  • 是连续的,生长方向是向下的,即向着内存地址减小的方向增长。 :在Windows下,是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和的最大容量是系统预先规定好的,在WINDOWS...
  • (转)生长方向

    2013-09-27 20:08:00
    51的是向高地址增长,INTEL的8031、8032、8048、8051系列使用向高地址增长的堆栈;但同样是INTEL,在x86系列中全部使用向低地址增长的堆栈。...那么哪一个向上,哪一个向下呢?人们对数据访问是习惯于向...
  • 函数调用原理

    2020-03-11 18:02:26
    int A () { int ret = B(); return ret;...栈向下生长 寄存器ebp 寄存器esp 内存区域 Text段:代码 Data段:堆、栈、静态数据段 BSS(Block Started by Symbol segment):初始化为0的全局变量 ...
  • /* 生长方向和内存的存放方向 的开口向下,高地址在上,低地址在下 内存的存放方向:自下向上 大端模式下:的高地址对应数据的低位 小端模式下:的高地址对应于数据的高位 */ #define _CRT_SECURE_...
  • 为什么和堆的生长方向不一样

    千次阅读 2013-01-22 22:39:51
    生长方向 8051的是向高地址增长,INTEL的8031、8032、8048、8051系列使用向高地址增长的堆栈;但同样是INTEL,在x86系列中全部使用向低地址增长的堆栈。其他公司的CPU中除ARM的...那么哪一个向上,哪一个向下
  • 栈区也叫临时区,是程序启动时系统自动分配和释放,堆区是程序员malloc()出内存大小,并释放free()若未释放 系统可能会回收,更可能造成内存泄漏/栈属性//栈向下生长的,//栈的生长方向和内存空间buf存放方向是两...
  • 堆栈的生长方向和空栈满的区别

    千次阅读 2016-08-16 17:18:31
    在STM32中,堆栈是 向下生长的满  PUSH {R0} ; *(--R13)=R0。R13 是 long*的指针  POP {R0} ; R0= *R13++  在压栈时,如果是先减地址再存,则是向下生长的,反之,相反。  满,堆栈指针指向的是最后一个...
  • ###Date: 2018-1-30 ###Author: SoaringLee =====================================================...向下生长的,即从高地址到低地址。 不同的系统在存储数据时是分大端(bit-endian)小端(little-e
  • 2018-01-29 21:45:45
    堆是向下生长,但这只是大体方向,实际上内存可能在堆上的任意位置分配。 ”递增“是数据入栈时堆栈指针的值增加,即堆栈从低地址向上增长。 “递减”是数据入栈时堆栈指针的值减少,即堆栈从高地址向下增长。 ...
  • 生长方向:的开口向下,堆的开口向上, 每压入一个内存块,即在的下端开辟出来,该内存块的首地址是在该内存块的最下面, 内存块里的数据生长方向,是向上的(与本身的生长方向是相反的),这一点对堆来讲也适用...
  • 回溯

    千次阅读 2020-01-19 14:45:52
    首先必须明确一点也是非常重要的一点,向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,底和栈顶,那么栈顶的地址要比底低。对x86体系的CPU而言,其中: ---> ...
  • ucosii 系统,任务

    2019-04-03 15:37:20
    1.之前一直不了解堆栈向下生长、向上生长究竟表示什么意思。最近仔细学习了下,简而言之,向下生长是指数据从高地址向低地址增长;向上生长就是数据从低地址向高地址增长。 堆栈增长演示: 上图显示了堆栈 向上...
  • RTT的

    2019-10-18 07:52:30
    向下生长:递减方式,即栈顶是的最后一个地址,数组的最后一个元素。 向上生长:递增方式,即栈顶是的首个元素的地址,数组首个元素。 RTT的线程向下生长是单片机RAM中一片连续的内存空间 2018年12月29...
  • 类型

    2013-04-12 14:07:36
    向下增长:压栈时,指针的值减小,即向低地址方向生长,为递减堆栈 从指针所指的位置,可分为满堆栈和空堆栈 满堆栈:栈顶指针指向最后压入的元素。 空堆栈:项指针指向下一个可以存放元素的空间。 ...
  • 堆和区别

    2017-10-02 22:15:36
    ②生长方向:栈向低地址扩展(即”向下生长”),是连续的内存区域;堆向高地址扩展(即”向上生长”),是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。 ③空间...
  • C语言函数调用剖析

    2017-02-24 09:21:25
    首先必须明确一点也是非常重要的一点,向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,底和栈顶,那么栈顶的地址要比底低。 2.EIP/EBP/ESP寄存器 对x86体系的CPU而言,...
  • 栈顶和底示意图

    千次阅读 2019-10-09 07:35:22
    在操作系统中,向下生长的。 栈顶和底不是上下决定,而是有入栈方向决定! 转载于:https://www.cnblogs.com/aakuang/p/3514568.html
  • 和堆的区别

    2019-08-17 11:58:50
    栈向低地址扩展(即”向下生长”),是连续的内存区域; 堆向高地址扩展(即”向上生长”),是不连续的内存区域。这是由于系统用链表来存储空闲内存地址,自然不连续,而链表从低地址向高地址遍历。 3、空间大小: ...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 256
精华内容 102
关键字:

栈向下生长