个人理财 堆是如何在C ++中工作的 - 傻瓜

堆是如何在C ++中工作的 - 傻瓜

目录:

视频: Our Miss Brooks: Boynton's Barbecue / Boynton's Parents / Rare Black Orchid 2024

视频: Our Miss Brooks: Boynton's Barbecue / Boynton's Parents / Rare Black Orchid 2024
Anonim

地址的函数堆是你的C ++程序可以根据需要访问的一块不规则的内存块。了解它为什么存在以及如何使用它。

正如可以将一个指针传递给函数一样,函数可以返回一个指针。返回double的地址的函数声明如下:

double * fn(void);

但是,返回指针时必须非常小心。要了解危险,您必须了解变量范围。

<! --1 - >

在C ++中有限的作用域

作用域是变量定义的范围。考虑下面的代码片段:

//只要程序正在运行,全局函数就可以访问以下变量//全局函数int intGlobal; //下面的变量intChild只能访问函数,并且只有在C ++正在执行child()或者一个函数的时候才被定义// child()调用的函数void function(void){int intChild;} //下面的变量intParent有函数// scope void parent(void){int intParent = 0;儿童(); int intLater = 0; intParent = intLater;} int main(int nArgs,char * pArgs []){parent();}

这个程序片段从变量intGlobal的声明开始。这个变量从程序开始执行直到终止。你说intGlobal“有程序范围。 “甚至在main()函数被调用之前,你也会说变量”进入了范围“。

函数main()立即调用parent()。处理器在parent()中看到的第一件事是intParent的声明。此时,intParent进入作用域 - 也就是说,intParent被定义并可用于函数parent()的其余部分。 ()中的第二个语句是对child()的调用。函数child()再一次声明了一个局部变量,这次是intChild。变量intChild的范围仅限于函数child()。从技术上讲,intParent没有在child()的范围内定义,因为child()不能访问intParent;但是,执行child()时,变量intParent将继续存在。

当child()退出时,变量intChild超出范围。 intChild不再是可访问的,它不再存在。 (由intChild占用的内存被返回到通用池以供其他事情使用。)

当parent()继续执行时,变量intLater进入声明的范围。在parent()返回到main()的时候,intParent和intLater都超出了范围。

由于intGlobal在本例中是全局声明的,所以这三个函数都可以使用它,并且在程序的整个生命周期中保持可用状态。

在C ++中检查范围问题

下面的代码段编译没有错误,但不起作用(你不喜欢吗?):

double * child(void){double dLocalVariable; return&dLocalVariable;} void parent(void){double * pdLocal; pdLocal = child(); * pdLocal = 1.0;}

这个函数的问题是dLocalVariable仅在函数child()的范围内定义。因此,在从child()返回dLocalVariable的内存地址的时候,它指向一个不再存在的变量。 dLocalVariable以前占用的内存可能被用于别的东西。

这个错误非常常见,因为它可能以多种方式蔓延。不幸的是,这个错误不会导致程序立即停止。实际上,程序在大多数情况下都可以正常工作 - 也就是说,只要以前由dLocalVariable占用的内存不会立即被重用,程序就会继续工作。这种间歇性问题是最难解决的问题。

在C ++中使用堆提供解决方案

范围问题源于C ++在程序员准备好之前取回本地定义的内存。所需要的是由程序员控制的一块内存。她可以分配内存并在需要时将其恢复 - 不是因为C ++认为这是个好主意。这样的内存块被称为堆。

堆内存是使用new关键字分配的,然后是要分配的对象的类型。新的命令将大块的内存从堆中分离出来,足以容纳指定类型的对象并返回其地址。例如,下面的代码从堆中分配一个双变量:

double * child(void){double * pdLocalVariable = new double; return pdLocalVariable;}

现在这个函数可以正常工作。虽然变量pdLocalVariable在函数child()返回时超出了作用域,但是pdLocalVariable所引用的内存不会。由new返回的内存位置不会超出范围,直到使用关键字delete(它专门为此设计)返回堆中:void parent(void){// child()返回地址//堆堆内存double * pdMyDouble = child(); //存储一个值* pdMyDouble = 1. 1; // … //现在将内存返回给堆delete pdMyDouble; pdMyDouble = 0; // …}

这里,child()返回的指针用于存储double值。内存位置完成功能后,返回到堆。函数parent()在堆内存返回后将指针设置为0,这不是必需的,但是这是一个非常好的主意。

如果程序员在删除后错误地在* pdMyDouble中尝试存储某些内容,程序将立即崩溃并显示一条有意义的错误消息。

<!你也可以使用new来从堆中分配数组,但是你必须使用delete []关键字返回一个数组:

int * nArray = new int [10]; nArray [0] = 0;删除[] nArray;技术上新的int [10]调用新的[]运算符,但它与新的相同。

堆是如何在C ++中工作的 - 傻瓜

编辑的选择

添加新的SketchUp图层并在图层之间移动实体 - 虚拟图层

添加新的SketchUp图层并在图层之间移动实体 - 虚拟图层

是SketchUp非常有用的一部分,他们可以让你的生活变得更轻松。以下是如何在Sketchup中添加新图层以及如何将实体移动到不同图层的方法。添加新图层按照以下步骤将图层添加到SketchUp文件:选择“窗口”→“图层”。图层...

全部关于地理位置快照和SketchUp - 虚拟

全部关于地理位置快照和SketchUp - 虚拟

当您将地理位置快照导入SketchUp ,您可以访问Google庞大的地理数据存储库;快照不仅仅是漂亮的图片:导入快照地理位置自动定位您的位置。这意味着快照设置您的模型的经纬度,并定位在正确的主要方向。任何阴影研究你...

如何在SketchUp中使用场景动画区域

如何在SketchUp中使用场景动画区域

将区域视图与场景组合在一起以创建动画展示您的SketchUp模型都是一种有用且令人印象深刻的方式。基本的想法是,您可以使用场景来创建动画,其中您的剖面在您的模型中移动。以下是您可能需要使用此技巧的几个原因:如果...

编辑的选择

Drupal友好的网页寄存公司 - 傻瓜

Drupal友好的网页寄存公司 - 傻瓜

网页寄存公司为您提供访问Web服务器,您可以在其中安装Drupal并使您的网站在Web上可见。一些公司为您安装Drupal或为您提供一键安装,为您节省了一些工作量。如果您决定自己跳过Drupal的安装,请考虑通过以下方式之一获取帐户...

Drupal花园功能 - 傻瓜

Drupal花园功能 - 傻瓜

让您有机会查看和使用所有Drupal花园功能,可以创建一个新的站点,然后选择自定义选项而不是其中一个已安装的模板:确保已经登录,然后单击我的站点链接。这样做打开了Drupal花园站点经理。点击创建...

Drupal园林主题生成器 - 傻瓜

Drupal园林主题生成器 - 傻瓜

Drupal花园设置完成后,有一些乐趣和玩你的网站上的主题。使用Drupal Gardens Theme Builder控制网站的外观是与安装Drupal自身副本不同的主要方式。但是你不会错过太多...

编辑的选择

上一次显示一张照片(全屏播放)如何在您的照片上一次显示一张照片(全屏播放)尼康D5300 - 傻瓜

上一次显示一张照片(全屏播放)如何在您的照片上一次显示一张照片(全屏播放)尼康D5300 - 傻瓜

很可能您已经在尼康D5300上播放了播放模式。但是,在数码相机上查看照片有不同的选项。对于正常播放 - 即每次只能查看一张照片 - 请执行以下步骤:

如何自定义尼康D3300的优化校准 - 傻瓜

如何自定义尼康D3300的优化校准 - 傻瓜

当您使用尼康D3300的内置原始处理器,您可以尝试不同的优化校准设置,了解每个设置对图像的影响。当您使用免费的Nikon软件Nikon ViewNX处理图像时,您可以选择相同的选项。该程序的原始转换器,以及在Adobe Photoshop中找到的那些...

如何在HDMI屏幕上显示实时预览预览 - 假人

如何在HDMI屏幕上显示实时预览预览 - 假人

尼康D7100相机连接到HDMI(高清晰度多媒体接口)设备,以在该屏幕上查看实时显示输出。摄影师经常使用此功能,因为摄影师需要比相机显示器提供更大的主题。使用此选项时,会出现一些问题:...