C++ 0428 指针和空间分配

2022-08-10 14:25:39

文件

打开文件

ifstream 是用于读取文件的istream流,
ofstream是用于写文件的ostream流,
!ost检测文件是否成功打开。

I/O错误处理
good()操作成功
eof()到达输入尾部
fail()发生某些意外情况(例如,我们要读入一个数字,却读入了字符‘x’)
bad()发生严重的意外(如磁盘读故障)


读取单个值

将程序分解为易管理的子模块

读取结构化的文件


在内存中的表示

读取结构化的值
谨记编写高质量代码的最好途径是阅读大量代码。


向量和自由空间

在C++中,一种可以保存地址的数据雷西兴称为指针(pointer),
它在语法上使用后缀*来区分,因此double*表示“指向double的指针”。

保存地址的对象被称为指针。
int* ptr = &var; //ptr保存var的地址

int x = 17;
int* pi = &x; //int指针

double e = 2.71828;
double* pd = &e; //double指针

*pi = 27; //正确:可以将27赋予pi指向的int
*pd = 3.14159; // 正确:可以将3.14159赋予pd指向的double
*pd = *pi; // 正确:可以将一个int(*pi)赋予一个double(*pd)

int i = pi; //错误:不能将一个int*赋予一个int
pi = 7; // 错误:不能将一个int赋予一个int*

char* pc = pi; //错误:不能将一个int*赋予一个char*
pi = pc; // 错误:不能将一个char*赋予一个int*

sizeof运算符


自由空间和指针

定义的全局变量分配内存(称为静态存储(static storage))。

编译器还会为你预留调用函数时所需的空间,函数需要用这些空间保存其参数
和局部变量(称为栈存储(stack storage)或自动存储(automatic storage)).


内存布局:
代码
静态数据
自由空间

C++语言用称为new的运算符将“自由空间”(free store,又称为堆(heap))变为可用状态。

double* p=new double[4]; //在自由空间中分配4个double
这段代码要求C++运行时系统在自由空间中分配四个double,并将指向第一个double的指针
返回给我们。

char* q = new double[4]; // 错误:将double*赋予char*


自由空间分配

通过指针访问数据

double* p = new double[4]; //在自由空间中分配4个double
double x = *p; //读取p指向(第一个)对象
double y = p[2]; // 读取p指向的第三个对象


指针范围
指针带来的主要问题是一个指针并不“知道”它指向多少个元素。
double* pd = new double[3];
pd[2] = 2.2;
pd[4] = 4.4;
pd[-3] = -3.3;

为什么指针不会记住自己的大小? 很显然,我们可以设计一个能记住大小的“指针”,
vector差不多就是如此。


12.4.4 初始化

对于内置类型,使用new分配的内存不会被初始化。如果想初始化单个对象,你可指定一个值
,就像我们对P2所做的:*p2=5.5.注意{}初始化语法。它与[]相对,后者表示“数组”。

对new分配的对象数组,我们可以指定一个初始化器列表。
double* p4 = new double[5] {0,1,2,3,4};
double* p5 = new double[] {0,1,2,3,4}; //可以省略元素数目

当我们定义自己的类型时,可以更好地控制初始化。如果类型X有一个默认构造函数,我们会得到:
X* px1 = new X; //一个默认初始化的X
X* px2 = new X[17]; //17个默认初始化的X

如果类型Y有一个构造函数,但不是默认构造函数,我们需要显示地初始化:
Y* py1 = new Y; // 错误,无默认构造函数
Y* py2 = new Y{13}; //正确:初始化为Y{13}
Y* py3 = new Y{17}; //错误, 无默认构造函数
Y* py4 = new Y{17} {1,...,16};


空指针

用名字nullptr表示空指针是C++11的新特性,因此在旧代码中,人们通常使用0(零)
或者NULL代替nullptr。两种旧的替代方法都会导致混淆和错误,因此优先选择更专用的nullptr.


自由空间释放

delete有两种形式:
delete p释放new分配给单个对象的内存。
delete p释放new分配给对象数组的内存。


两次删除一个对象是一个糟糕的错误。
int* p = new int[5];
delete p; //很好,p指向由new创建的对象

delete p; //错误:p指向的内存时由自由空间管理器所拥有的

第二个delete p带来两个问题:
你已不再拥有指针指向的对象,因此自由空间管理器可能已经改变了它的内部数据结构,
导致你无法再次正确执行delete p。

自由空间管理可能已“回收”p指向的内存,因此p现在可能指向其他对象;删除这个对象
会引起错误。


析构函数

  • 作者:宁静以致墨
  • 原文链接:https://blog.csdn.net/baiyibin0530/article/details/89674860
    更新时间:2022-08-10 14:25:39