篇幅长从 https://www.cnblogs.com/buchizaodian/p/11511256.html 提取出来

七、指针和自由存储空间

 1.寻址运算符 *

#include<iostream>
using namespace std;
void main() {
int a = ;
int b = ;
cout << &a<<endl;
cout << &b << endl;
cout << sizeof(a) << endl;
}

打印

012FFA34
012FFA28

为什么地址+4个字节后不是连续的?
根据系统,有可能是不连续的。

为什么b的地址要比a的地址小?

栈的声明地址从高到低。

根据系统也是有可能不同...

2.指针

定义指针只要在类型和变量中间即可,中间的空格会被忽略

    int*p = &a;
int* p = &a;
int *p = &a;
int * p = &a;

--

#include<iostream>
using namespace std;
void main() {
int a = ;
int *p = &a;
cout << &a << endl;//a的地址
cout << p << endl;//指针p中存放的值,这个值是个地址
cout << *p << endl;//p地址指向的值
cout << &p << endl;//p本身也有个地址,不过目前没有人引用它
}

空指针

    int* p = NULL;//空指针指向的地址为0
cout << p << endl;//

0-255的地址为内存地址,不允许访问

野指针

指向一个已删除的对象或未申请访问受限内存区域的指针

int* p = (int *)0x88554;

 3.指针的危险性

C++创建指针时计算机将分配用来存储地址内存,但不会分配指针所指数据的内存。

4.地址和数字的区别

地址和整数是两个不同的类型(虽然看上去一样)

    int *p = 0x00ED1821;//错误
int *p = (int *)0x00ED1821;//正确方式,转成地址

这里的 0x00ED1821 是一个十六进制数值,而不是一个地址。

5.使用new分配内存

(1)编译时分配内存

int a = ;
int* p = &a;

像这种方式,是编译时分配的内存

(2)运行时分配内存

指针的最大作用是程序运行阶段分配未命名的内存存储数据

    int* p = new int;
*p = ;

这种方式下只能通过指针来访问内存,new int 会根据类型所占用的空间找到一个长度合适的内存块,并返回地址

普通方式分配的内存在栈中,new分配的在堆中

(3)静态分配和动态分配

http://blog.sina.com.cn/s/blog_c290a2290101kpvr.html

C++中的对象可以:

(11)静态分配,即编译器在处理程序源代码时分配;

(22)动态分配,在程序执行时调用运行时刻函数分配;

静态与动态内存分配的两个区别:

(11)       静态对象是有名字的变量,直接对其进行操作;动态对象是没有名字的变量,通过指针间接地对其操作。

(22)       静态对象的分配与释放是由编译器自动处理,动态对象的分配与释放必须由程序员显式的管理,通过new和delete两个表达式完成。

主要区别:静态分配效率较高,缺少灵活性,要求在程序执行之前就知道所需内存的类型和数量。故:存储未知数目的元素需要动态内存分配的灵活性。

 6.delete释放内存

当数据不再使用时,用delete释放 new分配的内存。

delete会释放调p指向的内存,p本身不会被删除掉

 delete p;

如果忘记释放,被分配的内存块再也无法使用,会发生内存泄漏。

C++标准指出:不要尝试释放已经释放过的内存块,这可能带来一个不确定的情况发生。

7.使用new创建动态数组

int* p = new int[];

new会返回的第一个元素的地址

那么访问第一个元素可以使用两种方式

    p[] = ;//赋值
cout << *p << endl;//方式1
cout << p[] << endl;//方式2

释放数组占用内存,时需要加上 []

delete [] p;

指针移动

    p[] = ;
p = p + ;
cout << *p << endl;//结果会指向数组的第二个元素

p+1  vs里运行结果报错???

 8.使用 new delete 应遵守的规则

如果使用new为一个实体分配内存,则应使用delete来释放

如果使用new[]为数组分配内存,则应使用delete来释放

不要使用delete来释放不是new分配的内存

不要使用delete释放同一个内存两次

对空指针应用delete是安全的

9.指针和字符串

char f[] = "roes";
const char* p = "wren";

这里的“wren”是一个字符串的地址

字符串是常量要用const修饰

10.使用new创建动态结构

成员不能用.的方式来调用,因为这种结构没有名称,可使用专门的运算符 -> ,或者 (*stu).age

#include<iostream>
using namespace std;
void main() {
struct Student
{
int age;
string name;
}; Student* stu = new Student;
stu->age = ;
stu->name = "Tom";
cout << stu->age << endl;
cout << (*stu).name << endl;
}

11.管理内存的方式

(1)自动存储

函数内部定义的常规变量使用自动存储

  当该函数被调用时自动产生,结束时自动消亡

   自动变量通常存储再栈中(后进先出)

(2)静态存储

整个程序执行期间一直存在的存储方式

  可以在函数外定义或者使用关键字static

(3)动态存储

使用new的变量属于动态存储,比上两种存储方式更加灵活

  new和delete共同管理了一个内存池。

  这种方式存储在堆中

  

(4)线程存储

(4)C++ 复合类型-指针的更多相关文章

  1. go语言 类型:基础类型和复合类型

    Go 语言中包括以下内置基础类型:布尔型:bool整型:int int64 int32 int16 int8 uint8(byte) uint16 uint32 uint64 uint浮点型:floa ...

  2. C语言中的复合类型

    复合类型 一.掌握的类型 1. 指针数组 int * arr[10]; //arr是一个数组,有10个元素,每个元素都是一个指针,即arr是一个指针数组 int a,b,c,d; arr[0] = & ...

  3. 学习C++.Primer.Plus 4 复合类型

    本章介绍的有复合类型有: 数组. 字符串. 结构. 共用体. 指针 数组: 声明数组时数组长度必须为常量(或const). 只有初始化时可以用“=”,其它时候均不可以给数组直接赋值,除了赋值的元素以外 ...

  4. C++Primer快速浏览笔记-复合类型

    C++Primer2.3节介绍了两种复合类型:引用和指针 1.引用 引用并非对象,它只是为一个已经存在的对象所起的别名. 一旦初始化完成,引用将和它的初始值对象一直绑定在一起,不能重新绑定到另一个对象 ...

  5. c++学习总结--复合类型,const。

    复习c++,有必要对一些东西做一下笔记,方便以后学习,如有问题,欢迎提出. 首先,最常用两种复合类型应该是引用和指针. 所谓复合类型,是在基本类型基础(如:int)上定义的类型. 引用是c++的一个复 ...

  6. go - 复合类型 array, slice, map

    Go 语言支持复合类型: 数组:array 切片:slice 指针:pointer 字典:map 通道:chan 结构体:struct 接口:interface 1. array   同一类型数据的集 ...

  7. C++PrimerPlus第6版 第四章——复合类型

    1,复合类型主要包含:数组.结构.联合.枚举.类.指针.引用等. 2,数组.长度必须确定.即编译阶段,数组的长度就得确定好.所以只能使用常量(#define.const)声明数组长度.如果使用变量声明 ...

  8. 变量和基本类型——复合类型,const限定符,处理类型

    一.复合类型 复合类型是指基于其他类型定义的类型.C++语言有几种复合类型,包括引用和指针. 1.引用 引用并非对象,它只是为一个已存在的对象所起的另外一个名字. 除了以下2种情况,其他所有引用的类型 ...

  9. c++中的复合类型

    复合类型是指基于其他类型而定义的类型. 而这里介绍的是引用和指针.并且指针和引用都提供了对其他对象的间接访问. 引用 引用还是很好理解的,就是为对象起了另外一个名字,引用类型引用另外一种类型. 通常将 ...

随机推荐

  1. Process Monitor监控进程操作注册表如何实现?

    http://zhidao.baidu.com/link?url=Kqav4qkQSprC5FnpHPOGJvhqvY9fJ9-Vdx9g_SWh4w5VOusdRJo4Vl7qIdrG4LwRJvr ...

  2. android SlidingDrawer

    SlidingDrawer把内容从屏幕上隐藏,允许用户拖动把手将内容显示到屏幕.SlidingDrawer可用于垂直或水平.它由两个视图组成的:handle,让用户拖拉的;content,连在hand ...

  3. Python笔记(四)_字符串的方法

    字符串的方法 []表示该参数时可选的,start和end参数表示范围 count(sub[, start[, end]]) 返回sub在字符串里边出现的次数 find(sub[, start[, en ...

  4. anaconda 安装2个python环境 亲测

    本机环境: anaconda3,pyhon3.7.4 配置第2个python环境,安装python3.6 > conda create --name tensorflow python=3.6 ...

  5. PHP 实现小偷程序

    为什么使用“小偷程序”? 远程抓取文章资讯或商品信息是很多企业要求程序员实现的功能,也就是俗说的小偷程序.其最主要的优点是:解决了公司网编繁重的工作,大大提高了效率.只需要一运行就能快速的抓取别人网站 ...

  6. MySQL的共享锁与排它锁编码演示

    一.行锁之MySQL  使用SELECT ... FOR UPDATE 做事务写入前的确认 以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEA ...

  7. HDFS文件的基本操作

    HDFS文件的基本操作: package wjn; import java.io.BufferedInputStream; import java.io.BufferedReader; import ...

  8. SpringBoot整合Druid,密码加密

    1.application.yml配置 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/jby?serverTimezone=UTC& ...

  9. js常用扩展方法

    在日常的开发过程中,经常会碰到javaScript原生对象方法不够用的情况,所以经常会对javaScript原生方法进行扩展.下面就是在实际工作时,经常使用的一些方法,做一下记录,有需要的可以拿去. ...

  10. Java 枚举(enum)详解

    概念: Java1.5发行版本中增加了新的引用类型--枚举类型(enum type).枚举类型是指由一组固定的常量组成合法值的类型.在Java虚拟机中,枚举类在进行编译时会转变成普通的Java类. 创 ...