没有STL的C ++动态数组

时间:2012-08-22 15:57:47

标签: c++ arrays

这是作业的一部分,但我只是要求澄清:

  

从ATM.txt加载数据并将它们存储在动态数组中(ATM类型,   程序启动时不是STL。

如何在没有STL的情况下进行动态数组?我想也许分配意味着使用指针," ATM类型"把我扔了。

再次提到:

  

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

- 不属于作业

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

例如

5
abc
def
hij
kml
mno

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

//编辑 在Account.h文件中定义一个类帐户,其中包含数据成员:customer id,BSB号等

我假设帐户和ATM类型是那些类。

5 个答案:

答案 0 :(得分:4)

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

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

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

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

删除对象析构函数中的分配使用RAII原则,以确保在不再需要数组时删除该数组。

这又增加了一个危险:如果你复制这个数组对象,那么你最终会得到两个试图删除同一个数组的对象,这是一个灾难。为防止这种情况,您需要考虑Rule of Three。编写复制构造函数和复制赋值运算符以分配新数组并复制内容;或删除它们。 (如果你正在学习老式的C ++,那么就不能删除成员函数,因此你必须将它们声明为私有而不是实现它们。)

  

使用STL不是更聪明吗?

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

答案 1 :(得分:1)

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

使用数据填充数组后,将最大大小扩展一些并分配新数组。这允许您将旧数组中的数据复制到新数组中,然后继续添加项目,直到再次用完空间。

答案 2 :(得分:0)

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

基本上你必须:

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

当然,像std :: vector一样实现像STL这样的容器并不是一件容易的事(最终还是一个不错的功课!)。

我可以建议以下内容:

  • 尽可能避免重新分配。当空间完成时,分配一些空间以避免连续调用realloc(参见std :: vector :: reserve)
  • 删除元素时,避免重新分配空间。分配后,除非内存使用率过高,否则请按分配的空间,以避免将来重新分配。

答案 3 :(得分:0)

  

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

std :: vector的内部结构并不神奇。可以自己手动执行std :: vector为你做的事情。

听起来这就是你应该为这项任务做的事情;制作您自己的“ATM类型”,可以安全地从ATM.txt文件管理读取数据,以及一个“帐户类型”,可以保存accounts.txt文件中的数据。你应该从编写任务的人那里得到一些澄清,说明他们对这些类型的设计/使用方式的准确程度。回顾你所拥有的任何课程材料应该告诉你在使用动态数组方面你需要知道什么。

答案 4 :(得分:-1)

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

  1. 创建一个类myDynamicArray
  2. 使类包含int或long以存储数组大小
  3. 使用“new”为您的阵列分配内存。从赋值,看起来它可能是一个字符串数组,或者,如果教授严格禁止STL(字符串现在被认为是STL),它将是一个字符数组数组。
  4. 编写一个插入方法,在插入之前,检查数组的大小(参见#2),如果不够大,则使其变大。不使用预C ++函数的一种方法,我认为这是最好的,因为这是一个C ++类,是分配一个更大的新数组 - >复制旧数组中的数据 - >插入任何新数据。多大了?你可以选择,比如每次新分配增加20%。微软的C#分配了“下一个最大的素数”元素,尽管它们具有非常快的内存分配例程。
  5. 完成后,不要忘记删除()动态数组(“完成”意味着取决于赋值)。请注意,一旦程序退出,从技术上讲,内存应该自动释放,但不要自己释放它是非常糟糕的做法(想想那些不经常关闭的大型非学术程序)。
  6. 我会避免其他用户提供的模板代码。我确信这是一个很好的代码,但它会引起人们的注意,使用早期C ++类中的东西。

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