首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

地址、指针与引用

而指针变量也是一个变量,在内存中也占空间,不过比较特殊的是它存储的是其他变量的地址。...在32位的机器中,每个进程能访问4GB的内存地址空间,所以程序中的地址采用32位二进制数表示,也就是一个整型变量的长度,地址值一般没有负数所以准确的说指针变量的类型应该是unsigned int 即每个指针变量占...,它们的地址分别是:[ebp - 10h] 、 [ebp - 14h]、 [ebp - 18h],在给指针变量赋值时首先将变量的地址赋值给临时寄存器,然后将寄存器的值赋值给指针变量,而通过间接访问时也经过了一个临时寄存器...对于地址我们可以进行加法和减法操作,地址的加法主要用于向下寻址,一般用于数组等占用连续内存空间的数据结构,一般是地址加上一个数值,表示向后偏移一定的单位,指针同样也有这样的操作,但是与地址值不同的是指针每加一个单位...只有同类型的指针之间才可以相减。而指针的乘除法则没有意义,地址之间的乘除法也没有意义。

70410

指针|内存和地址

指针 1. 声明为指针并不会改变这些表达式的求值方式。 2. 一个变量的值就是分配给这个变量的内存位置所存储的数值。 3. 变量的值就是分配给该变量的内存位置所存储的数值,即使是指针变量也一样。...内存中的每个位置由一个独一无二的地址标识。 5. 内存中的每个位置包含一个值。 6. 变量名字与内存位置之间的关联不是硬件所提供的,它是由编译器为我们实现的。...所有这些变量给了我们一种更方便的方法记录地址--硬件仍然通过地址访问内存位置。...%d\n",b); printf("c: %f\n",c); //变量的值 printf("*d: %p\n",d); printf("*e: %p\n",e); //指向地址所...存储的数值 printf("*d ->value: %d\n",*d); printf("*e ->value: %f\n",*e); //变量本身所存储的地址 printf("&

38320
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【Linux课程学习】: 进程地址空间,小故事理解虚拟地址,野指针

    一.小实验(不是物理地址,而是虚拟地址/线性地址) Linux大哥,你别骗我,我之前一直给我的时物理地址,没想到你给我一个虚拟的地址,我真的看透你了。...现在我们创建一个子进程,打印同一个值的地址是不是一样的,按理来说,他们地址是不一样的,因为数据相互独立。但是真实的结果是如何呢? 看上面的图,我们居然发现他们的地址是一样,啊?...那么我们下面就把gval的值修改一下,看是不是地址会不一样。 好像结果不是这样的,不是要写时拷贝,是因为(Linux大哥)C语言给了我们一个虚拟的地址。...mm_struct中就有每个地址区域的地址空间。有起始位置和结束位置。 PCB中,有一个mm_struct结果体指针,指向一个mm_struct结构体。 mm_struct是由谁来初始化的?...四.为什么要有虚拟地址+页表 野指针就是有一个虚拟地址,在进行映射的时候,发现找不到真实的物理地址,或者权限不对,就会发生错误。操作系统就可以控制该进程终止。

    10010

    初识指针(指针和指针变量、如何理解地址、指针类型的意义、void*指针、野指针、空指针)(笔记)

    一、指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。...&a;//pa指针变量 - 存放地址 - 地址又被存放指针 //int* pa,变量的类型,变量的名字 (变量 即 存放的地址) *pa;//*解引用操作符,*pa等价于a //& ---...* //取地址 解引用 return 0; } 二、指针和指针变量 指针:地址 指针变量:变量-存放地址 指针变量用来存放地址的...,指针变量并不完全等同指针, 但口头上 指针 一般是 指针变量 2.1指针变量的大小 1.指针变量是专门用来存放地址的,指针变量的大小取决于一个地址存放需要多大空间 32位机器上:地址线32根,地址的二进制序列就是...,导致该指针指向的内存地址仍然被占用,但该指针却不受控制。

    19910

    指针(*)、取地址(&)、解引用(*)与引用(&)

    指针(*)、取地址(&)、解引用(*)与引用(&) C++ 提供了两种指针运算符,一种是取地址运算符 &,一种是间接寻址运算符 *。...指针是一个包含了另一个变量地址的变量,您可以把一个包含了另一个变量地址的变量说成是"指向"另一个变量。变量可以是任意的数据类型,包括对象、结构或者指针。...指针与取地址 例程: int main() { int num = 3; int* p = # // 将变量num的地址取出来,存到指针p中 printf("%d 的地址是...("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p, *p); *p = 100; printf("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p...7 指针p所指向的地址为 0x7ffeefbff3b8 , 该地址上所保存的值为100 123 注意这里*操作符为解引用操作符,它返回指针p所指的对象的值(注意不是地址)。

    88220

    【Linux】地址空间&&虚拟地址

    在32位和64位下的地址空间大小是不一样的,为了方便这里使用32位来表述。32位从低到高一个有4GB的地址空间范围,实际上这个地址空间当中打印出来的地址,是该空间内对应的地址。...所以子进程和父进程看到的虚拟地址是一样的,并且它们的页表也一样,指向的物理内存也一样,所以它们打印出来的地址也就是相同的了。...所以虚拟地址相同而物理地址不同。 3. 进程调度 Linux中的nice值并不是能任意调度的,而是从-20到19,这40个数字之间变换。...active指针和expired指针:active指针永远指向活动队列;expired指针永远指向过期队列。...没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了一批新的活动进程! 有问题请指出,大家一起进步!!!

    18510

    【linux】地址空间

    在Linux地址下,这种地址叫做 虚拟地址 我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理 OS必须负责将 虚拟地址 转化成 物理地址 。...程序内部使用的地址都是基于虚拟地址空间,页表负责将这些地址实时映射到实际的物理内存地址,为程序的正确执行提供支撑 03.Linux2.6内核进程调度队列 前面提到的nice值范围在[-20,19]...在 Linux 2.6 内核中,进程调度得到了很大的改进,以提高系统的效率、响应性和可扩展性。...Linux 2.6 使用了一种称为 Ø(1)调度器 的调度算法,这种算法通过使用多个调度队列来达到高效调度。...expired指针 active指针永远指向活动队列 expired指针永远指向过期队列 但是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。

    9810

    一级指针和二级指针,取地址和不取地址调用函数区别及其应用

    1.指针定义区别 一级指针是指向某个数据的指针,它存储的是该数据的内存地址。通过一级指针可以访问和修改该数据的值。一级指针多用于单个数据的操作,例如传递参数、返回结果等。...二级指针是指向一级指针的指针,它存储的是一级指针的内存地址。通过二级指针可以访问和修改一级指针指向的数据的值。二级指针多用于对一级指针进行操作,例如动态内存分配和释放、指针数组等。...参数传递:通过一级指针可以将变量的地址传递给函数,并在函数中修改变量的值。通过二级指针可以将指针的地址传递给函数,并在函数中修改指针指向的数据。...在main函数中,通过传递&list作为参数调用insertNode函数,实际上是将链表的头指针list的地址传递给了二级指针head。...为了解决这个问题,我们需要将头节点的指针的地址传递给insertNode函数。

    10110

    指针值传递、地址传递和引用传递

    下面简单的用函数栈帧空间图分析一下: 值传递,形参的修改不会影响到实参 二、指针的地址传递 由于实参是一个一级指针的地址,要传入这样的地址给形参,这需要一个对应类型的二级指针来接受一级指针的地址...* p = NULL; fun(&p); printf("p=%s\n",p); free(p); return 0; } 上述代码的执行结果是:p=hello 指针的地址传递经常用在没有头节点的链表中...如果用一级指针接收发生的是值传递,要修改其值必须用二级指针接收一级指针的地址,在这个地址对应的内存块进行修改。...三、指针的引用传递 用二级指针操作一级指针的内存往往让人难以理解,甚至往往还会发生内存泄漏的风险,在C++中,可以通过指针的引用简化这样的内存模型,实际上在编译器内部还是处理为二级指针,当使用时,解引用为一级指针...,编译器在内存中开辟了临时量,用于存储引用变量的地址,一但使用引用变量就进行解引用。

    1.7K30

    Linux编程--地址计算

    背景 在学习Matrix的ELF Hook的过程中,发现在查找Library基址指针的时候,对于指针的运算有一些疑惑,特此记录。...= 'x') { continue; } } 在计算addr_size的时候,使用的两个(char *)的减进行运算,为何能得到地址的大小?...7ac10cf000-7ac10d1000 rw-p 000c2000 fd:00 3463 /system/lib64/libc.so 在本地运行后,打印的日志如下...而first_bar_pos与maps_line则这是上面两个字符串的地址,那么这两个地址相减,就是5da215f000字符串的大小,正好是10个字节。 所以就认为计算出来的地址长度为10。...privbits 相应的,在获取到addr_size的大小之后,通过first_bar_pos+addr_size+1+1,获取到的字符数组首地址指向的就是r-xp这一段文本了。

    1.1K00

    Linux:进程地址空间

    三、进程地址空间         其实我们的之前所学的线性地址,并不是真正的物理内存,而是在PCB内部有一个指针指向了一块进程地址空间,然后虚拟地址会通过页表来映射到具体的物理地址。...本质上其实就是一个内核数据结构,和PCB一样,地址空间也是需要被操作系统管理的:先描述再组织。 而每一个进程都有自己的进程地址空间,PCB内部有一个指针指向这块空间!... 进程PCB结构体里有对应的进程地址空间指针,所以进程切换就以为这进程空间地址空间被切换,而页表会被存储在CPU的cr3寄存器中,这其实属于进程的上下文信息,在进程切换的时候会被进程带走,后面再恢复过来...这是有Linux的内存模块去管理的,进程并不需要关心。 结论4:其实变量名在定义的时候就已经被转化成一个个虚拟地址了,而我们之所以有a和&a,本质上是为了区分想获取的是变量的值还是地址。...结论5:以前我们所学习的C内存管理,其实本质上是进程地址空间,而内存管理是由Linux替我们完成的,我们上层语言并不需要关心具体的细节,只需要正常去通过对应的线性地址去使用就行了。

    13110

    【Linux】进程地址空间

    首先我们可以肯定的是,这个地址一定不是物理地址!同一块物理地址访问到的值一定是一样的!...下面我们来讨论一下 二、进程地址空间 1、页表 我们在之前讲到的程序地址空间的说法其实是错误的,正确来说应该叫进程地址空间,上面我们所说的地址叫做虚拟地址,也叫做线性地址,既然叫做虚拟地址,那当然就不是真实的物理地址了...,也就是虚拟地址是相同的,我们不是复制出了两个地址空间,这里需要注意 内核空间中有父子进程的task_struct,它们里面有指向各自页表的指针 其中上方是父进程的地址空间,下方是子进程的地址空间,子进程直接复制父进程的地址空间...,然后再将g_val改成100,然后页表的物理地址指向该地址,这个过程是写时拷贝,我们前面提到过 其中MMU起到的作用是负责将进程虚拟地址转换为物理地址,当 CPU 需要访问内存时,会将虚拟地址发送给...就只可读了 其他的还有对应代码和数据是否已经加载到内存等等一系列的其他属性 页表的本质属于进程的硬件上下文,在进程切换的时候会带走这些信息,被存储在CPU寄存器中,task_struct中有指向页表地址的指针

    7910

    Linux进程地址空间

    Linux进程地址空间是学习Linux的过程中,我们遇见的第一个难点,也是重中之重的重点。虽然它很难,但是,等我们真正懂得了这样设计的原理,我们不禁会感叹:这真的是太妙了。...1个进程的虚拟空间中可能有多个虚拟区间,对这些虚拟空间的组织方式有两种,当虚拟区较少时采取单链表,由mmap指针指向这个链表,当虚拟区间多时采取红黑树进行管理,由mm_rb指向这棵树。...指针pgt指向该进程的页目录(每一个进程都有自己的页目录),当调度程序调度1个程序运行时,就将这个地址转换成物理地址,并写入控制寄存器。...arg_start,结束arg_end,环境段的开始env_start,结束env_end unsigned long saved_auxv[AT_VECTOR_SIZE]; struct linux_binfmt...2.父子两个进程修改同一变量的原理 写时拷贝技术 我们在取地址操作中得到的地址都是虚拟地址,虚拟地址通过一张表格和内存之间建立映射关系,进而通过虚拟地址找到真正的内存中的地址,得到代码和数据。

    12210

    【Linux】进程地址空间

    显示相同地址,却是不同的值 下面在Linux上验证 创建test.c文件 st.c  ⮀...被不影响父进程 ,说明进程具有独立性,而进程是由内核数据结构+代码和数据组成的,独立性体现在数据上,所以通过写时拷贝的做法 使一个进程的变量被修改,不影响另一个进程的变量 value通过写时拷贝变成两个变量,打印不同变量的地址时...对第一个问题的解答 直接用的是虚拟地址,找到地址不是目的,而是该地址所对应的内容 页表:将虚拟地址转化成物理地址,左侧填充虚拟地址,右侧填充物理地址 当有一个虚拟地址,通过特定的地址空间想访问特定的区域时...越界,访问到另一个进程的数据,若再写入数据,则破坏了另一个进程的数据 一个进程因为野指针问题访问到另一个进程的上下文,导致另一个进程出现故障,进程与进程之间的独立性无法保证 7....进程地址空间+页表的意义: 1.防止地址随意访问,保护物理内存与其他进程 若没有地址空间的存在,则直接使用cPU调用物理地址,会有野指针的问题存在 2.将进程管理和内存管理进行解耦合 因为有虚拟地址和页表的存在

    3K10

    linux进程地址空间

    ,因此随着我们的函数的调用,这个static修饰的局部变量的数值不会发生改变; 3.2虚拟地址 我们可以看到这个上面的实验,刚开始的这个打印的g_val是100,后来这个对应的是200,但是这个变换之后这个地址是不变的...,怎么可能一个变量一个地址,但是这个变量的数值却不一样,这个就是因为这个打印的结果不是真实的物理地址,而是我们的虚拟地址; 3.3页表概念的引入 页表是一张显示这个虚拟地址和真真实的物理地址的关系的映射表...)因此这个父进程的变量在子进程里面也是存在的,但是因为这个进程具有独立性,因此这个会发生写实拷贝,这个物理地址会发生变化,开辟新的物理地址去存储这个修改后的变量的数值; 因此这个上面的打印结果,打印的是虚拟地址...,这个虚拟地址子进程就是拷贝的父进程的,所以这个打印的结果是一样的,但是这个实际上的物理地址不是一样的; 3.4谈谈细节 到底什么是进程地址空间:数据总线排列组合形成的地址的范围[0,2^32); 进程地址空间实际上就是我们的进程的一个可以使用的范围...对于任何一个进程,都会创建一个task_struct结构体对象,这个指针指向我们的进程地址空间对象,这个里面就有我们的各种区域的划分,方便我们对于这个区域的管理; 3.6进程地址空间的存在意义 让所有的进程以一个统一的视角去看待内存

    4510

    初识Linux · 地址空间

    g_val和它的地址,当count到5的时候就修改g_val,但是后续还是要一直打印,父进程要做的工作就是一直打印g_val和g_val的地址。...现象如下: 打印5秒之后,g_val的值如愿以偿的被修改了,此时让父进程打印的时候,我们发现一个怪事,打印的时候为什么父进程中的g_val没有变化呢?.../* first hole of size cached_hole_size or larger */ pgd_t * pgd; /* 页表目录指针...page_table_lock, in other configurations by being atomic. */ struct mm_rss_stat rss_stat; struct linux_binfmt...从安全问题上来看,我们之前写代码的时候,如果出现了非法请求,比如野指针访问,进程就会被直接杀死,这是因为地址空间已经划分好了空间,如果访问的地址超过了这个空间,就是非法访问,OS层面检测出越界,肯定就直接杀死该进程了

    7810
    领券