【问题标题】:Reading a large file into an array causes a crash将大文件读入数组会导致崩溃
【发布时间】:2013-01-16 04:18:35
【问题描述】:

我有一个任务,我需要输入一个 7 位数字(电话号码)并检查是否在 pi 的数字中找到它。 pi 的数字存储在提供的空格分隔的文本文件中。这似乎相当简单:将输入分解为一个数组,将 pi 的数字读入一个数组,然后检查是否找到匹配项。长话短说,我得到了令我满意的程序。我们提供了文本文档,其中 pi 的数字是 10、100 等的倍数,最多可达 100 万位。我的程序最多可以处理 100,000 位数字。但无论出于何种原因,在 100 万位数的文件中,它都会因一般 Windows 错误而崩溃。我没有关于它为什么崩溃的信息,也没有给出错误消息(除了通用的“问题导致该程序停止工作”消息)。

注意分配状态的限制我不能使用任何面向对象的代码,除了 cin、cout 和文件流对象(这个限制是因为我们还没有进入类并且他们不希望我们使用不知道它们是如何工作的)。

无论如何,我正在寻找有关程序崩溃原因的见解。我在每个应该需要它们的变量(包括计数器和函数返回)上使用长整数,这应该足够了,因为它们可以达到大约 20 亿,并且这里不应该有任何大于一百万的数字。

感谢您的帮助。过去几个小时我一直在这样做,但没有成功。

const long int numberOfDigits = 1000000;
int digitsOfPi[numberOfDigits];

【问题讨论】:

  • 堆栈通常没有那么大。绝对不足以容纳一百万个数字。
  • 这听起来像是一个包含有价值课程的好作业。
  • 请注意,您可以通过意识到单个数字不需要 32 位数字来提高内存性能。您可以在此处改用 char 数据类型,它是 8 位的——足以容纳 0 到 9 的值(实际上只需要 4 位)。我 NOT 建议这样可以将 100 万字节的数组放在堆栈上 =) 给定的答案仍然适用。

标签: c++


【解决方案1】:
int digitsOfPi[numberOfDigits];

堆栈 没有足够的空间来容纳这么大的数组。堆栈是存储automatic variables(AKA 局部变量)的位置。当执行进入函数时,会自动为局部变量分配内存,并在函数返回时释放。由于这种自动内存管理,堆栈很棒,但一个限制是它的大小是有限的。

大对象应该放在上。1堆是一个巨大的内存池,您可以随时从其中动态分配块。堆和栈的区别在于你负责分配和释放堆内存。它不会自动为您释放。

要在 C++ 中在堆上分配内存,请使用 new 运算符,每个 new 都有一个对应的 delete,以便在不再需要内存时释放内存。 (或者在我们的例子中,我们使用new[]delete[],因为我们正在处理一个数组。)

// Allocate memory on the heap.
int *digitsOfPi = new int[numberOfDigits];

// Use it.

// Then free it.
delete[] digitsOfPi;

// Or better yet, once you're allowed to use the STL...
std::vector<int> digitsOfPi;

不过,更大的问题是为什么您需要一次将 π 的所有数字读入内存。一个更好的设计,虽然代码更复杂,但只需要固定的 O(1) 内存量——比如,一次 7 位。

另见


1您可以探索编译器的选项来增加堆栈大小,但这不是正确的解决方案。

【讨论】:

  • 感谢您的回答。这绝对有效,看看“新”关键字应该做什么,这是有道理的,但你能解释一下这个“堆栈”是什么吗?
  • 可能还值得一提delete []?万一他不知道呢?
  • @KarthikT 读取顺序文件时您不会过度搜索,并且通过输入缓冲,您不会浪费读取。一次读取 1 个字节就可以了。
猜你喜欢
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-29
相关资源
最近更新 更多