C语言,获得堆栈增长方向的一种方法

转载:http://blog.chinaunix.net/uid-2413049-id-109836.html

在阅读wget源代码的过程中,发现一个用C语言实现,获得堆栈增长方向的巧妙方法

wget版本为1.11.4

实现代码:

static void
find_stack_direction ()
{
  static char *addr = NULL;     /* Address of first `dummy‘, once known.  */
  auto char dummy;              /* To get stack address.  */

if (addr == NULL)
    {                           /* Initial entry.  */
      addr = ADDRESS_FUNCTION (dummy);

find_stack_direction ();  /* Recurse once.  */
    }
  else
    {
      /* Second entry.  */
      if (ADDRESS_FUNCTION (dummy) > addr)
        stack_dir = 1;          /* Stack grew upward.  */
      else
        stack_dir = -1;         /* Stack grew downward.  */
    }
}

简化后的相关定义:

static int stack_dir;           /* 1 or -1 once known.  */

#define ADDRESS_FUNCTION(arg) &(arg)

find_stack_direction函数使用函数递归的方法
第一次进入,由于addr为NULL,所以将字符变量dummy的地址赋值给静态变量addr
第二次进入,由于静态变量addr已赋了值,所以进入 "Second entry."
接着,将第二次进入的dummy地址和第一次进入的dummy地址相比较
如果值为正,则堆栈向高地址增长;否则,堆栈向低地址增长

巧妙地运用了“函数递归也使用了堆栈”的思想 ,漂亮 :)

时间: 2024-10-10 01:29:39

C语言,获得堆栈增长方向的一种方法的相关文章

C语言打印杨辉三角(2种方法)

杨辉三角是我们从初中就知道的,现在,让我们用C语言将它在计算机上显示出来. 在初中,我们就知道,杨辉三角的两个腰边的数都是1,其它位置的数都是上顶上两个数之和.这就是我们用C语言写杨辉三角的关键之一.在高中的时候我们又知道,杨辉三角的任意一行都是的二项式系数,n为行数减1.也就是说任何一个数等于这个是高中的组合数.n代表行数减1,不代表列数减1.如:第五行的第三个数就为=6. 现在我们按第一种思路来写:先定义一个二维数组:a[N][N],略大于要打印的行数.再令两边的数为1,即当每行的第一个数和

ios 设置屏幕方向的两种方法

第一种:通过人为的办法改变view.transform的属性. 具体办法: view.transform一般是View的旋转,拉伸移动等属性,类似view.layer.transform,区别在于View.transform是二维的,也就是使用仿射的办法通常就是带有前缀CGAffineTransform的类(可以到API文档里面搜索这个前缀的所有类),而view.layer.transform可以在3D模式下面的变化,通常使用的都是前缀为CATransform3D的类. 这里要记住一点,当你改变

Win7 SP1语言包微软官方下载地址及使用方法 2

情形一:如果您的系统版本是企业版.旗舰版,可以在Windows update中检测语言包按照提示下载安装即可.如果觉得Windows update不方便的话,可以在本文第二部分中下载所需的语言包,下载完毕后双击 .exe 可执行文件就可以安装语言包. 安 装完成之后切换显示语言的方法:在开始菜单左下角的搜索框中输入“语言”作为关键字,并从搜索结果中选择“更改显示语言”,随后可以看到更改界面.在“选 择显示语言”下拉菜单中,列出了本机安装的所有语言包,从中选择要使用的语言,并单击“确定”,注销并重

栈增长方向与大端/小端问题

转:http://www.cnblogs.com/xkfz007/archive/2012/06/22/2558935.html 栈增长和大端/小端问题是和CPU相关的两个问题.在内存管理中,与栈对应是堆.对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向:对于栈来讲,它的生长方式是向下的,是向着内存地址减小的方向增长.在内存中,“堆”和“栈”共用全部的自由空间,只不过各自的起始地址和增长方向不同,它们之间并没有一个固定的界限,如果在运行时,“堆”和 “栈”增长到发生了相互覆盖时,称为“

栈增长方向和数组增长方向

栈的增长方向和变量内存分配没有关系 帖子回复: 1 一年多过去了,今天我搜到了这个帖子.正好我看到的一本书里面是这样说的:默认的函数内部变量的压栈操作为:从上到下.从左到右,采用4字节对齐.数组的压栈方法略有不同,即从最后一个元素开始,直到起始元素为止,即采用从右向左的方法压栈.书名是 <C语言进阶:重点.难点与疑点> 2 所谓 栈空间的生长方式由高到低,指的是(以 X86 体系结构为例),一些默认使用 sp (stack pointer)寄存器的指令,如 push, pop, call, r

使用C语言判断栈的方向

这一问题主要是如何判读出先后入栈的变量的地址大小,比如有a, b两个变量一先一后被定义,如果a的地址大于b的地址,则说明是以低地址方向增长的,反之,往高地址方向增长. 在写C程序的时候不能简单直接的定义两个变量来比较它们的地址大小,因为这样很有可能编译器会做优化,最终导致结果不真实.为避免这种编译器优化的情况,可以采用将变量定义到函数中,然后递归调用该函数.例如下面的代码: #include <stdio.h> static int stack_direction = 0; static vo

c语言基础----堆栈队列链表

堆 堆则是一种经过排序的树形数据结构,常用来实现优先队列,他的特点在于形成某种优先的结构.在计算机经常用到,比如优先队列,或者是优先进程管理. 堆(也叫二叉堆)的性质: 1.任何一个节点,都不大于他的父亲节点. 2.必须是一颗完全二叉树 栈 在数据结构中,栈是一种可以实现“先进后出”(或者称为“后进先出”)的存储结构.假设给定栈 S=(a0,a1,…,an-1),则称 a0 为栈底,an-1 为栈顶.进栈则按照 a0,a1,…,an-1 的顺序进行进栈:而出栈的顺序则需要反过来,按照“后存放的先

大端小端系统_union_栈的增长方向

一道题引发的思考: 1.看一下之前写的union的特点,理解一下共享内存的概念 2.栈的增长方向是从高地址向低地址增长(数组比较特别,a[0]在低地址,a[n-1]在高地址)(堆由低地址到高地址存储) 3.小端系统 指 低字节存在低地址中,高字节存在高地址中:大端系统反之. 如上,联合体变量是4个字节,当A={"ab"};即str[0] ~ str[3]依次为: 'a'  'b'  '0'  '0',其中str[0]在低地址. 默认小端系统的情况下,A.l的低字节 对应 低地址,即00

C语言中常见的内存错误与解决方法

常见的错误 关于内存的一些知识已在内存分配中提及,现记录与分享常见的内存错误与对策. 类型 1:内存未分配成功,却使用了它. 方   法:在使用之前检查指针是否为NULL. 1)当指针p是函数的参数时,在函数入口处用语句assert(p!=NULL)进行断言检查. 2)当使用malloc或new来申请内存时,应该用if(p != NULL)进行防错检查. 类型 2:引用了尚未初始化的指针 原   因:内存的缺省初始值究竟是什么并没有统一的标准,在使用之前都进行初始化. 1)没有初始化的观念. 2