linux c的指针与内存

指针

指针的声明用*a来表示,指针是保存内存地址的一种数据类型。另外,取地址用&a来做。

指针的调用和传值

int a = 100;
int point_t(int *a)
...
point_t(&a)

内存

计算机可以控制、接收电流的高(1)低(0)电位或者通(1)断(0)电路,这就产生了计算机能识别的二进制。

内存的最小单位是字节(Byte,1 Byte = 8 bits,一个字节是八个二进制位),一个字节可以表示00000000至11111111种意义(可以表示0~255元素)。

一个十六进制的数字可以表示4位二进制的数字(1111 = 0xf)。一个字节,既可以用8个二进制数字表示,也可以用2个16进制的数字表示。

32位操作系统

32位os的cpu地址总线是32位,支持232 个地址位,暨寻址空间是32位,最多能访问0~232次方(大约4GB空间)个内存地址,可以理解为只能访问并操纵最多4GB的内存空间。每个内存地址位记录一个唯一的内存地址编号,每个地址编号对应存储一个字节。

证明:
232=210 * 210 * 210 * 2 2
= 1024 byte * 1024 byte * 1024 byte * 4
= 1kb * 1024 byte * 1024 byte * 4
= 1mb * 1024 byte * 4
= 1gb * 4 = 4gb

内存管理

内存由os统一管理(编号、规划内存),内存大小的也会将多根内存条合并后统一计算。os还会对多个程序进行统一调度、分配内存空间,防止不同程序对于内存的相互侵占。

64位os内存管理草图

例如,64位os,应用程序使用前48位,暨0x7fffffffffffffff以下的内存地址位,系统内核使用后边的16位内存地址位。

这样把用户的内存和os的内存隔离开,还有个好处就算,os的内存不会被大量占用,避免机器卡住、卡死、死机等状态的发生。因此,只要os可用,就可以用os将关闭应用程序,解决安全等问题。

内存规划

如上图所示,os把内存进行了分片,分为系统内核、栈、自由内存区、堆、数据段、代码段

代码段

代码被编译后,会存到磁盘中,形成2进制文件。运行这个程序(例如,调用main函数),其实就是os把二进制数据文件(也就是计算机指令)加载到内存代码段中。C语言不能直接操作代码段的地址。

在代码段,可以知道程序的二进制字节大小。例如定义如下函数:

p &rect 0x4005a6
p &quadrate 0x4005dd

用quadrate 的地址高度减去rect的地址高度,就是加载到内存中rect函数的大小

数据段

数据段存储静态变量、全局变量、常量,他们都会分配独立的地址,且地址唯一

堆内存

栈内存

栈内存记录变量的地址和值,还会记录程序已经执行了多少行的行号,记录程序当前状态,调用哪个函数,函数中有哪些变量,变量值。

变量名其实就是地址别名,变量其实就是内存地址,系统通过变量告诉cpu要到哪个地址取数据。

#include <stdio.h>
int global = 0;

int rect(int a, int b)
{
    static int count = 0;
    count++;
    global++;
    int s = a * b;
    return s;
}

int quadrate(int a)
{
    static int count = 0;
    count++;
    global++;
    int s = rect(a, a);
    return s;
}

int main()
{
    int a = 3;
    int b = 4;
    int *pa = &a;
    int *pb = &b;
    int *pglobal = &global;
    int (*pquadrate)(int a) = &quadrate;
    int s = quadrate(a);
    int s2 = (*pquadrate)(a);//定义一个函数指针
    printf("%d\n", s);
    return 0;
}

操作系统对于内存的管理

代码端

gcc编译器对于代码是如何优化的

函数栈就不一样了,一个函数可用被多次调用,一个变量也会被多次调用

gcc会优化存储
我们在 中看到的地址,例如0x7fffffffddfc就是一个整型变量的首地址,然后ddfc、ddfd、ddfe、ddff都是这个整形变量的地址。(因为,一个整形变量占用四个字节,四八32,一个整形是32bits)

但是 gcc会做优化

不连续赋值,编译器会优化,为了让cpu操作指令更方便更快,为了提升程序的执行效率,因此,会对源代码进行优化。那么编译之后的指令存储,跟我们编写的代码的顺序可能会不一样。例如,会先定义基本类型的,然后将基本类型的地址连续放到内存中,然后再放其他类型的,都是把同一类型的变量放到一起。这样可用让程序执行更快,至于为什么,下面会说。另外,64位操作系统下,指针占8个字节(32位操作系统,指针占4个字节),因为,是64bits,一个字节存8个bits,因此,需要8个字节才能将全部的地址存储下来。

栈这个内存空间,保存的就是函数当前运行的状态。包括代码执行到多少行指令,每一个内存空间到底是什么类型的数据,什么数值。在栈中,函数或者变量会被多次调用,每次调用都会分配新的独立的栈地址。函数调用就是先进后厨的栈内存结构。因此,越到栈顶的函数的地址越小。栈是从后向前压栈的。栈,越往后调用的地址越小。从栈顶向下分配的。

函数指针

函数指针定义后,也可以调用函数,这种做法经常用在我们做 回调函数来使用

一个地址,用括号包起来,表示指向一个代码段的函数。

带*号表示要访问地址对应的字节块是啥

数组、动态堆类型创建、指针运算

数组申明的内存排列

C语言中的数据声明,也是在栈内存中保存的
c语言不做指针代码的安全检测。因为,地址是连续排放的,因此,指针运算符就用上了

指针运算

指针偏移,的运行效率非常高,性能非常好,这样比cpu根据地址总线取地址要更方便一些

int *p=&a;

p+=3;表示将指针偏移3个int 变量占位符。

在指针上做的加个减,其实做的是地址的偏移。

数组其实就是一种地址的表示

int array[3];

可用表示为,int p = array;
此时,
p也就指向了array数组的第一个元素的地址。

因此我们这样写

p[0] == array[0];
p[1] == array[1];
p[2] == array[2];

因此,在c中,任何用数组操作的地方,都可以用c来代替。因此,数组是一种指针常量。但是 ,指针是指针变量。因此,定义了数组,数组就永远指向某个地址

但是 ,指针指向的地址是会改变的
这就是区别。

字符数组和指针字符串

字符串 指针 竟然 存在 代码段?

注意:c语言字符串数组,以\0结尾,什么时候遇到\0也就标识着字符串结束了。

malloc可以分配地址

c语言字符串是原始字符串,其实就是字节数组。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容