C专家编程---随记(五)

一、段

1.含义:对于目标文件而言,它是二进制文件中简单的区域,里面保存了和某种特定类型(如符号表条目)相关的所有信息。

对于UNIX中:段表示一个二进制文件相关的内容块
对于intel x86中:段表示一种设计结果,即地址空间并非一个整体,而是分成一些64k大小的区域

2.一个程序(可执行文件.exe)是由BSS段、数据段、文本段所组成的
(1)
BSS段:指用来存放程序中未初始化的全局变量的一块内存区域,属于静态内存分配。

数据段:保存经过初始化的全局和静态变量以及它们的值,属于静态内存分配。

文本段:通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

在这里插入图片描述
(2)数据段和BSS段的整个区段称为数据段,BSS只保存可执行文件中得到的大小,但不占可执行文件的任何空间。

(3)堆栈段:用于保存局部变量、临时数据、传递到函数中的参数,也就是auto自动变量。另外需要堆(heap) 空间 ,用于动态分配的内存,调用malloc()函数即可。

(4)虚拟地址空间的最低部分未被映射,它位于进程的地址空间内,但未被赋予物理位置,所以任何对它的引用都是非法的。

—它用于捕捉使用空指针和小整型值的指针引用内存情况

在这里插入图片描述

(6)查看堆栈的大致位置,数据段、BSS段

#include <stdio.h>
char a[10];
int p = 1 ;
main()
{
	int i ;
	printf("The 堆栈  is near %p\n",&i);
	printf("The 数据段  is near %p\n",&p);
	printf("The BSS段  is near %p\n",a);
	return 0;
}

3.堆栈段
(1)它包含一种单一的数据结构:堆栈,“后进先出”,值可以压到堆栈中,也可以通过栈取出值

(2)主要三个用途:
a.堆栈为函数内部声明的局部变量提供存储空间,这些变量是自动变量

b.进行函数调用时,堆栈存储与此有关的一些维护性信息,这些信息被称为堆栈结构,也就是过程活动记录。

c.堆栈也可以被用作暂时存储区,例如使用alloca()函数分配的内存就是在堆栈中,但是如果想要让内存在函数调用结束之后,仍然有效,那就不能用alloc来分配,因为它会被下一个函数调用所覆盖。

(3)在不同的系统中:

UNIX:当进程需要更多空间时,堆栈会自动增长。
------一般使用某种形式的虚拟内存,并且当试图访问当前系统分配给堆栈空间之外时,会产生一个硬件中断,被称为页错误!

MS-DOS:在建立可执行文件时,堆栈的大小必须同时确定,而且它不能在运行时增长

二、过程活动记录

1.含义:一种用于支持过程调用,并记录调用结束以后返回调用点所需要的全部信息的数据结构。

2.目的:跟踪调用链——那些函数调用了哪些函数,当下一个return语句执行后,控制将返回何处等问题。

过程活动记录的规范描述
局部变量
参数
静态链接(用于上层引用,C语言不引用)
指向先前的结构指针
返回地址

TIPS:
a.允许嵌套函数的语言中,活动记录一般包含一个指向它的外层函数的活动记录指针,这个指针被称为静态链接。

b.一个指向词法上外层范围的数据项的引用被称为上层引用。

c.C语言不运行嵌套函数!!

三、控制线程

----如何解决在进程中支持不同的控制线程

只需要简单为每个控制线程分配不同的堆栈即可

四、setjmp 和 longjmp

1.它们都是通过操纵过程活动记录实现的
(1)setjmp(jmp_buf j)必须首先被调用,它表示:使用变量j记录现在的位置,函数返回0

setjmp保存了一份程序的计数器和当前的栈顶指针

(2)longjmp(jmp_buf j, int i)可以接着被调用,它表示:回到j所记录的位置,将导致这个被保护的状态重新恢复,但是返回i!

当使用longjmp的话 ,j的内容被摧毁;并且它只跳回曾经到过的地方。
(3)

#include <stdio.h>
#include <setjmp.h>
jmp_buf buf;
banana()
{
	printf("in banana() \n");
	longjmp(buf,1);
 //以下代码不会显示
	printf("you'll never see this , because i longjmp'd");
}

main()
{
	if(setjmp(buf))
		printf("back in main\n");
	else{
		printf("first time through\n");
		banana();
	}
}

tips:要保证局部变量在longjmp过程中保持值唯一的话可靠方法是把它声明为volatile!

2.两者最大的用途是,错误恢复,只要还没有从函数返回,一旦发现一个不可恢复的错误,可以把控制转移到主输入循环,并从那里重新开始。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值