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



c语言中数组的内存建立

使用C语言编程,实际上使用的内存只有一种——虚拟内存。根据功能的不同在C语言中又将虚拟内存为分三类:栈区、堆区、静态数据区,无论单一变量还是数组,其内存分配都是如此。其中,栈区、静态数据区、堆区都会有...
  • zhuangchaoxian
  • zhuangchaoxian
  • 2015年11月28日 10:04
  • 281

C与虚拟内存

#include int add(int a,int b) { return a+b; } main() { int (*fun)(int )=(int (* )(int )) add; fun f=...
  • Einstein_1110
  • Einstein_1110
  • 2013年12月07日 22:28
  • 561

虚拟地址与虚拟内存的理解

在最开始看书的时候,我知道程序在运行时,不是全部加入内存当中的,当然,这个现在依旧正确,在有了虚拟地址空间这个概念以后,我一直认为是在硬盘中划分出一块虚拟内存出来,然后给每个程序4G的硬盘空间,作为这...
  • u014379540
  • u014379540
  • 2016年08月20日 19:25
  • 1268

虚拟内存与物理内存的区别,

第一层理解         1.每个进程都有自己独立的4G内存空间,各个进程的内存空间具有类似的结构           2.一个新进程建立的时候,将会建立起自己的内存空间,此进程的数据,代码等...
  • u012861978
  • u012861978
  • 2016年11月05日 21:39
  • 4796

虚拟内存

1、什么是进程(Process)和线程(Thread)?有何区别?   进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。线程是进程的一个...
  • u012813201
  • u012813201
  • 2017年04月13日 09:02
  • 96

20170722Windows12_1_虚拟内存

虚拟内存: 虚拟内存简介: 1:Windows下面,内存分为虚拟内存,物理内存(逻辑内存),虚拟内存和物理内存是相对应的,操作系统支持多进程运行,物理内存只有一块,需要执行某个程序的时候,就将其从虚拟...
  • qq_31622605
  • qq_31622605
  • 2017年07月23日 18:23
  • 100

缓存、内存、虚拟内存分析

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo4 许多人认为,“缓存”是内存的一部分,许多技术文章都是这样教授的,事实...
  • yemou_blog
  • yemou_blog
  • 2015年12月14日 11:13
  • 681

基于visual c++之windows核心编程代码分析(6)分配和释放可读可写的虚拟内存页面

我们在进行Windows核心编程,经常要用到读取虚拟内存。 我们来亲自实践一个分配与释放可读可写的虚拟内存页面,请见代码实现与注释讲解。 [cpp] view plain co...
  • flyingleo1981
  • flyingleo1981
  • 2016年12月08日 21:46
  • 378

数组在内存中的运行机制

深入数组 1.数组引用变量只是一个引用,这个引用 变量可以指向任何有效的内容,只有当该引用指向有效内存后,才可通过该数组变量来访问数组元素。 2.实际的数组对象被存储在堆(heap)中;如...
  • w18210042300
  • w18210042300
  • 2017年07月11日 09:25
  • 79

虚拟内存管理

MMU 现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要处理器中的MMU(Memory Management Unit,内存管理单元)提供支持。...
  • dongpanshan
  • dongpanshan
  • 2015年07月03日 08:52
  • 1185
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C与虚拟内存
举报原因:
原因补充:

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