C与虚拟内存

原创 2013年12月07日 22:28:53

一、C和C++的区别:C和C++的主要差别,C语言缺少对bool值,引用,模板,命名空间,面向对象,异常特性的支持。C比C++更适合底层开发,因为C能够提供稳定的ABI(Application Binary  Interface)接口。ABI不同于API ,API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译 ,然而ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。ABI掩盖了各种细节,例如:调用约定控制着函数的参数如何传送以及如何接受返回值;系统调用的编码和一个应用如何向操作系统进行系统调用;以及在一个完整的操作系统ABI中,对象文件的二进制格式、程序库等等。

C的函数调用:

#include<stdio.h>

int add(int a,int b)

{

return a+b;

}

main()

{

int (*fun)(int )=(int (* )(int )) add;

fun f=f(20);

printf("%d\n",r);

}

该程序尽管实参和形参不匹配,但是依然能够正常运行。

下面研究函数调用的本质:

函数执行的时候有自己的临时栈

函数的参数就在临时栈中,如果函数传递实参,则用来初始化临时的参数变量,如上函数,即使传递三个参数不会报错,程序会忽略第三个参数

#include<stdio.h>

int add(int *a,int *b)

{

return (*a)+(*b);

}

main()

{

int a=20;

int b=30;

int r=add(&a,&b);  \\传递指针变量,地址值

printf("%d\n",r);


int (*fun)(int )=(int (* )(int )) add;

fun f=f(20);

printf("%d\n",r);

}

二种函数结果返回方式,直接返回、通过函数的参数返回。

通过参数来返回值,(告诉必须是指针)

指针指向的区域必须事先分配,在函数中操作该区域,函数返回后,该区别不会销毁


函数指定三种调用方式,__stdcall _cdecl _fastcall,这些方式直接影响编译器。

(linux中可通过gcc test.c  -s与cat test.s查看对应的汇编代码)

1.决定我们函数栈压栈的顺序,函数参数从右向左压栈

2.决定函数栈清空的方式

3.决定了函数的名字转换方式

stdcall调用者清空

cdecl有专用参数来标识清空方式,统一清空

fastcall自己在返回前空间

几种类型的指针

far near huge指针

near 16

far 32位

huge 综合


二.虚拟内存

  先看一个程序:

#include<stdio.h>

#include<stdlib.h>

main()

{

int *p=malloc(0);

*p=9999;

printf("%d\n",*p);

}

能够正常输出9999

一个程序程序不能访问另一个程序指向的空间,

每个程序的开始地址都是0X80084000,这个不是物理地址,是每个程序的逻辑地址,也即虚拟内存。

逻辑地址仅仅是编号,统带使用int 4字节整数表示,2的32次方,即4G的空间。每个程序提供4G的访问能力,逻辑地址与物理地址关联才有意义,这个过程称为内存映射。strace main跟踪程序执行,查以查看映射。虚拟内存的提出,目的在于不允许程序直接文章物理内存,提高程序的可靠性,有助于系统的稳定。

虚拟与物理 地址在映射的时候,有一个基本单位 4K 1000即内存页,

段错误:无效访问,访问了无法映射的物理地址。

合法访问:比如malloc分配的空间之外的空间,可以访问,但访问非法。

虚拟内存的分配

栈:编译器自动生成代码维护

堆:地址是否映射,映射的空间是否被管理

brk/sbrk 内存映射函数

帮助手册的使用,man      节      关键词

节为1-8     1:linux系统指令,shell命令

2:系统函数 查看brk/sbrk函数说明

                                3:标准C函数的帮助文档 

7:系统的编程帮助  man 7 tcp   常用的节

分配与释放内存:

int brk(void *end)  //分配空间,释放空间  与malloc 区别

1使用sbrk分配空间

2.使用sbrk得到没有映射的虚拟地址,得到一大块未分配的地址的首地址

3使用brk分配空间

4使用brk释放空间

void *sbrk(int size); //返回空间地址  如果是第一次运行,则返回没有映射的空闲空间首地址,

同时产生一个数据结构,指向该空间

sbrk与brk后台系统维护一个指针,指针默认是NULL,第一次调用sbrk,我们判定指针是否是0,是则得到大块空闲空间首地址来初始化指针

同时指针+参数size,否,则返回指针并把指针位置+size(参数

malloc 用brk来实现

作业:写一个程序查找1-10000之间所有的素数,并且存放到缓冲,然后打印。用数组实现太耗空间,缓冲用Sbrk/brk实现。

总结:

系统操作内存有哪下几种方式:智能指针、STL、new、malloc、brk/sbrk,依次上高级到低级。

int brk(void *)

void *sbrk(int )

如果成功brk返回0 sbrk返回指针

失败 brk返回-1 sbrk返回 (void *) -1

unix函数如果错误,修改一个内部errno

打印错误方法:

1.peror 打印详细信息

2.printf("memory:%m\n"):

3.printf("::%s\n",strerror(error));

补充知识,inux中重要的函数:子符串函数 string.h cstring、内存管理函数 malloc memset mamcmp memcpy bzero、错误处理函数、标准IO函数、时间函数、类型转换函数

作业:打印1-10000之间所有孪生素数

 打印当前的日期时间:格式

0000年00月00 00:00:00



相关文章推荐

内存管理API

一、进程的内存空间1、实现  为实现系统中每个进程都有一个私有的虚拟地址空间,系统为每个进程都创建了一个页目录和一组页表。每个进程的页表是独立的,而内核空间中的页表是共享的。  x86平台上,CR3寄...

*《精通Windows API》 5.4.2 分配和释放可读可写的虚拟内存页面

/* ************************************ *《精通Windows API》 * 示例代码 * virtual.c * 5.4.2 分配和释放可读可写的虚拟内存...
  • SJF0115
  • SJF0115
  • 2011年12月15日 16:32
  • 1116

GNU C Library 3 Virtual Memory Allocation And Paging 虚拟内存分配和页面调度——摘要

文档地址:https://www.gnu.org/software/libc/manual/html_node/Memory.html#Memory   3 虚拟内存分配和分页   3.1 进...

error C3859: 超过了PCH的虚拟内存范围;请使用“-Zm33”或更大的命令行选项重新编译

在vs中使用boost的时候,在stdafx中包含的boost头文件,然后就出现这个错误。 经过查找就是stdafx中包含boost头文件造成的。 解决办法如下: 产生的原因: 为了加...

c程序在虚拟内存中的地址顺序

c程序在虚拟内存中的地址从低地址到高地址的顺序依次是: text段(代码区)、.rodata段(常量区)、.data段(已初始化的全局变量区)、.bss段(未初始化的全局变量区)、堆、动态库映射...

深入理解Linux虚拟内存管理.pdf

  • 2017年09月30日 09:44
  • 44.64MB
  • 下载

虚拟内存linux

  • 2015年08月29日 21:32
  • 899KB
  • 下载

linux的虚拟内存swap分区的使用和配置

Swap空间的作用可简单描述为:当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被...
  • hj7jay
  • hj7jay
  • 2016年07月04日 17:51
  • 1969

Linux虚拟内存原理

  • 2014年06月13日 09:46
  • 8.5MB
  • 下载

虚拟内存课件

  • 2014年04月11日 09:25
  • 972KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C与虚拟内存
举报原因:
原因补充:

(最多只允许输入30个字)