(4)C++ 复合类型-指针

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

 

七、指针和自由存储空间

 1.寻址运算符 *

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

打印

012FFA34
012FFA28
4

为什么地址+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 = 6;
    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;//00000000

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

野指针

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

int* p = (int *)0x88554;

 

 

 3.指针的危险性

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

 

 

4.地址和数字的区别

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

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

 

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

 

5.使用new分配内存

(1)编译时分配内存

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

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

(2)运行时分配内存

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

 

    int* p = new int;
    *p = 10;

 

这种方式下只能通过指针来访问内存,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[10];

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

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

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

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

delete [] p;

指针移动

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

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

 

 

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

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

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

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

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

对空指针应用delete是安全的

 

9.指针和字符串

char f[10] = "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 = 10;
    stu->name = "Tom";
    cout << stu->age << endl;
    cout << (*stu).name << endl;
}

 

11.管理内存的方式

(1)自动存储

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

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

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

(2)静态存储

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

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

 

(3)动态存储

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

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

  这种方式存储在堆中

  

(4)线程存储

 

转载于:https://www.cnblogs.com/buchizaodian/p/11516266.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值