内存与指针杂谈

1、指针

1、数组指针
int(*ptr)[n]

()的优先级高,(*ptr)表示ptr是一个指针,指向一个int类型的一维数组,这个数组的长度为n,也可以说ptr的步长就是n。也就是说执行ptr+1时,ptr要跨过n个int的长度。

2、指针数组
int* p[n]

[]的优先级高,p和[]先结合表示一个数组,int*表示数组中元素的数据类型为int*。

3、复杂一点的指针
int* (*ptr)[n]

ptr是一个指向数组的指针,数组中的每个元素都是指向int的指针。

4、指针运算

指针运算:一个指针ptrold加(减)一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值加或减了n乘sizeof(ptrold所指向的类型)个字节。

5、指针变量和指针所指向的内存空间是两个不同的概念
6、指针做函数参数,是指针存在的最大意义

*p间接赋值成立的3个条件:

  1. 2个变量(通常一个实参,一个形参)。
  2. 建立关系,实参取地址赋给形参。
  3. *p形参去间接修改实参的值。

引申:函数调用时,用n级指针(形参)修改n-1级指针(实参)的值。

7、一个指针的内容
  1. 指针的类型。

  2. 指针所指向的类型。

  3. 指针的值或者叫指针所指向的内存区或地址

    • 指针的值都是指针本身存储的数值,这个数值将被编译器当做一个地址,而不是一般的数值,在32位程序里所有类型的指针的值都是一个32位整数,因为32位程序里内存地址都是32位长。
    • 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。
  4. 指针本身所占据的内存区。在32位平台里,指针本身占据了4个字节的长度。

2、内存

1、内存四区:
  1. 栈区(stack):由编译器自动分配释放,存放函数参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

  2. 堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两个概念。分配方式倒是类似于链表。

  3. 数据区:主要包括静态全局区和常量区,如果站在汇编角度细分的话还可以有很多小的区。

    • 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放。
    • 常量区:常量字符串就是放在这里。程序结束后由系统释放。
  4. 代码区:存在函数体的二进制代码。

2、变量

变量的本质:一段连续内存空间的别名。

数据类型的本质:固定大小内存空间的别名。

1、修改变量的方法
  1. 直接修改,int a = 10;
  2. 间接修改,内存有地址编号,拿到地址编号也可以修改内存,外挂的原理就是通过变量内存地址来修改变量值:&a = 1245024; ((int)(1245024)) = 10。
  3. C++中引用。
2、声明变量的意义
  1. 建立变量符号表。
  2. 变量的数据类型指示了系统分配多少内存空间。
  3. 变量的数据类型指示了系统如何解释内存空间中的值。
  4. 变量的数据类型确定了变量的取值范围。
  5. 不同的数据类型有不同的操作。
3、函数内存模型
  • 主调函数可以把堆区、栈区、全局数据内存地址传递给被掉函数。
  • 被掉函数只能返回堆区、全局数据。
4、避免产生野指针:
  • 定义指针时,把指针变量赋值为NULL。
  • 释放内存时,先判断指针变量是否为NULL。
  • 释放完内存后,把指针变量重新赋值成NULL

3、void与void*

  1. 如果函数没有返回值,那么应声明为void类型。
  2. 如果函数无参数,那么应声明其参数为void。
  3. 小心使用void指针类型,ANSI标准,不能对void指针进行算法操作。
  4. 如果函数的参数可以是任何无类型指针,那么应声明其参数为void*。

​ 例:典型的如内存操作函数memcpy,memset的函数原型:

void * memcpy(void *dest, const void *src, size_t len);
void * memset(void *buffer, int c, size_t num);

​ 这体现了内存操作函数的意思,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。

  1. void不能代表一个真实的变量。

C/C++ 内存与指针的更多相关文章

  1. Delphi 内存与指针

    源:Delphi 内存与指针 Delphi 的内存操作函数(1): 给字符指针分配内存 Delphi 的内存操作函数(2): 给数组指针分配内存 Delphi 的内存操作函数(3): 给结构体指针分配 ...

  2. 33.unique_ptr独享内存智能指针

    #include <iostream> #include <memory> #include <string> #include <vector> us ...

  3. 易错、经典问题:return不可返回指向栈内存的指针

    预备知识:内存的分类 C/C++程序占用的内存分为两大类:静态存储区与动态存储区.其示意图如下所示: 数据保存在静态存储区与动态存储区的区别就是:静态存储区在编译-链接阶段已经确定了,程序运行过程中不 ...

  4. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

  5. 结构体,内存,指针例题.DOC

    2015.1.30 递归函数:1.自身调用自己:2.要有结束条件!typedef 后面加分号:一般后面的重定义名加_,例如:typedef unsigned long int uint_16;结构体成 ...

  6. 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体

    1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...

  7. 关于被malloc分配内存的指针

    例如创建了一个链表指针p并为其malloc()分配了内存,那么这个指针指向的地方其实是有数据的. 你可以把p->data打印出来,会发现是一个随机值 因为只是分配内存而没有指定data的值,所以 ...

  8. C++虚函数和成员函数内存 this指针问题

    father* p=new son; p->disp(...); 发现有好多人this指针的本质有错误的认识,估计不少人一说起this指针,脑袋立即反应出:那个类里使用的this指针,那么这个指 ...

  9. C#使用内存和指针方式将字节数组转换为Bitmap

    /// <summary> /// 指针方式转 /// </summary> /// <param name="Width">图像的宽</ ...

随机推荐

  1. [luogu]P1800 software_NOI导刊2010提高(06)[DP][二分答案]

    [luogu]P1800 software_NOI导刊2010提高(06) 题目描述 一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每个软件划分成m个模块, ...

  2. docker-compose进行部署容器的时候,报错权限不足

    刚刚用docker-compose部署elk的时候,没有起来,查看日志的时候,发现在数据卷挂载的时候,报错权限不足. 由于日志不在了,这里就直接贴出解决办法. 问题原因及解决办法 原因是CentOS7 ...

  3. 【BZOJ4570】 [Scoi2016]妖怪

    Description 邱老师是妖怪爱好者,他有n只妖怪,每只妖怪有攻击力atk和防御力dnf两种属性.邱老师立志成为妖怪大师,于 是他从真新镇出发,踏上未知的旅途,见识不同的风景.环境对妖怪的战斗力 ...

  4. Android中播放声音

    在Android系统中,有两种播放声音的方式,一种是通过MediaPlayer,另外一种是通过SoundPool.前者主要用于播放长时间的音乐,而后者用于播放小段小段的音效,像按键音这种,其优点是资源 ...

  5. THU-CCF WC2019两开花记

    今年年初,清华大学举办的THUWC2019即将正式开启,我将继续扮演蒟蒻OIER,努力创造一个菜鸡的形象,THU-CCF WC两爆炸,笑掉各位大牙,大家多多关注. Day0 广州好热啊╰(‵□′)╯! ...

  6. Spring Data Jpa (五)@Entity实例里面常用注解详解

    详细介绍javax.persistence下面的Entity中常用的注解. 虽然Spring Data JPA已经帮我们对数据的操作封装得很好了,约定大于配置思想,帮我们默认了很多东西.JPA(Jav ...

  7. SQL模糊查询报:ORA-00909:参数个数无效

    用oracle数据库进行模糊查询时,控制台报错如下图所示: 原因是因为敲的太快,语法写错了 正确的写法是 pd.code like concat(concat('%',#{keyword}),'%')

  8. iOS 消息转发以及 NSProxy 实战

    最后更新: 2018-01-17 一.消息派发机制-NSObject 在 iOS 开发中, 调用对象的方法就是给对象发送一个消息.了解消息的派发机制对于iOS开发来说是一个很实用且强大的工具, 下面我 ...

  9. splice()、slice()、split()函数的区分

    1.slice(数组) 用法:array.slice(start,end) 解释:该方法是对数组进行部分截取,并返回一个数组副本:参数start是截取的开始数组索引,end参数等于你要取的最后一个字符 ...

  10. mysql 5.7分组报错问题 Expression #1 of ORDER BY clause is not in GROUP BY clause 的问题 MySQL

    解决方案: select version(),@@sql_mode;SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); ...