没有STL的C++动态数组

C++ dynamic array without STL

本文关键字:动态 数组 C++ STL 没有      更新时间:2023-10-16

这是任务的一部分,但我只是要求澄清:

从ATM.txt加载数据并将它们存储在一个动态数组中(ATM类型,而不是STL)。

在没有STL的情况下,我究竟该如何处理动态数组?我想也许分配意味着使用指针,"ATM类型"让我大吃一惊

再次提到:

将accounts.txt文件转换为动态数组(帐户类型,而非STL)

--不属于转让

我从来没有理解过使用内存不安全的操作,例如从第一行提取文件中的项目数:

例如。

5
abc
def
hij
kml
mno

使用STL(矢量或C++11数组)而不依赖文件中的数字,因为它可能不准确,导致缓冲区溢出等,这不是更明智吗?

//编辑在包含数据成员的文件Account.h中定义一个类Account:customerid、BSB号码等

我认为Account和ATM类型就是这些类别。

最基本的动态数组形式是使用new[]创建,并使用delete[]销毁:

ATM * atms = new ATM[count];
// do stuff with the array
delete [] atms;

然而,这带来了使用数组的代码可能引发异常、从函数返回或以其他方式阻止delete[]发生的危险。如果发生这种情况,那么您将丢失指向已分配内存的唯一指针,它将保持已分配但不可访问;这被称为内存泄漏。出于这个原因,最好将数组封装在一个类中,使用:

  • 存储指向数组的指针的成员变量,以及(可选)数组大小
  • 用于分配数组的构造函数和/或函数
  • 用于删除数组的析构函数
  • (可选)用于调整数组大小的函数

删除对象的析构函数中的分配使用RAII原理来确保数组在不再需要时被删除。

这又留下了一个危险:如果复制这个数组对象,那么最终会有两个对象都试图删除同一个数组,这是不合理的。为了防止这种情况发生,您需要考虑"三条规则"。要么写一个复制构造函数和复制赋值运算符来分配一个新数组并复制内容;或者删除它们。(如果你在学习老式的C++,那么你不能删除成员函数,所以你必须声明它们为私有函数,而不是实现它们)。

使用STL不是更明智吗?

通常,是的。但是,如果你正在学习C++,了解内存管理是如何工作的,以及如何让库为你处理它是一个好主意。这可能是这个练习的一部分要点。

这种分配的常见方法是自己模拟向量的自动扩展行为。为堆上的数据分配一个数组,并跟踪其长度和存储在数组中的项目数。

一旦您用数据填充了数组,就将最大大小扩展一些,然后分配一个新的数组。这允许您将数据从旧阵列复制到新阵列中,然后继续添加项,直到空间再次用完为止。

基本上,如果您需要在不使用STL的情况下实现动态数组,则必须明确处理内存分配/释放。

基本上你必须:

  • 在第一次构造或使用数组时,使用malloc分配空间
  • 跟踪插入/删除的图元
  • 完成分配的空间后使用realloc
  • 阵列销毁时释放分配的空间

当然,实现一个像std::vector这样的好的类似STL的容器并不是一件容易的任务(最终是一项很好的作业!)。

我可以建议如下:

  • 尽可能避免重新分配。当空间用完后,再分配一些空间,以避免继续调用realloc(请参阅std::vector::reserve)
  • 删除元素时避免重新分配空间。分配完后,除非内存使用率太高,否则让分配的空间保持原样,以避免将来重新分配

使用STL(矢量或C++11数组)而不使用它不是更聪明吗依赖文件中的数字,因为它可能不准确,导致缓冲区溢出等?

std::vector的内部并不神奇。您可以手动执行std::vector为您所做的操作。

听起来这就是你应该做的任务;制作您自己的"ATM类型",可以管理从ATM.txt文件中安全读取数据,以及一个可以保存accounts.txt文件中数据的"帐户类型"。你可能应该从写作业的人那里得到一些澄清,说明他们期望如何设计/使用这些类型。同样,回顾一下你所拥有的任何类材料,都应该告诉你在使用动态数组方面需要知道什么。

由于这是家庭作业,我们不想直接给出答案,但总的来说,我建议:

  1. 使类myDynamicArray
  2. 使类包含int或long以存储数组大小
  3. 使用"new"为阵列分配内存。从赋值来看,它可能是一个字符串数组,或者,如果教授严格禁止STL(字符串现在被认为是STL),它将是一个字符数组数组
  4. 编写一个insert方法,在插入之前,检查数组的大小(参见#2),如果不够大,则将其变大。在不使用C++之前的函数的情况下执行此操作的一种方法是分配一个较大大小的新数组-->从旧数组中复制数据-->插入任何新数据,我认为这是最好的方法,因为这是一个C++类。大多少?你可以选择,比如说,每增加一个分配,就增加20%。微软的C#分配"第二大素数"的元素,尽管它们有非常快速的内存分配例程
  5. 不要忘记在完成动态数组时删除()("finished"的含义取决于赋值)。请注意,一旦程序退出,从技术上讲,内存应该自动释放,但自己不释放内存是非常糟糕的做法(想想那些没有定期关闭的大型非学术程序)

我会避免其他用户提供的模板代码。我相信这是一个很棒的代码,但使用早期C++类中的高级代码会让人大吃一惊。

建议阅读:http://www.cplusplus.com/doc/tutorial/dynamic/