【问题标题】:C++ Can programs run out of stack memory even when plenty of memory is available?C++ 即使有大量可用内存,程序也会用完堆栈内存吗?
【发布时间】:2014-02-11 15:59:44
【问题描述】:

我正在为一个大文件编写解析器,我负责从输入文件读取的函数之一有一个名为 peek 的字符缓冲区。基本上,当main 反复调用这个函数时,peek 最终会被一些奇数覆盖。这是main 调用的函数。 bufferAsInt:

void bufferAsInt(ifstream &inf, int &i)
{
    char peek[3];
    inf.read(peek, 3);
    i = atoi(peek);

    //I'm not using the >> operator to read an int because the int is just
    //3 chars long in the input file and two consecutive integer values can
    //be written like this: 123456 for 123 and 456.
}

我发现当我将这些值写入输出文件时,当读取一个只有两位数长的 int 值时,第三位数字(或其他数字)将留在 char 缓冲区peek 和值会被错误地写入输出文件(这只发生在从输入文件中读取大量数据之后。)所以经过数万次迭代,当读取像15这样的数字时,会得到的值写入我的输出文件可能类似于156

为了解决这个问题,我将bufferAsInt 的实现更改为:

void bufferAsInt(ifstream &inf, int &i)
{
    char *peek = new char[3];
    inf.read(peek, 3);
    i = atoi(peek);
    delete [] peek;
}

(当然我是在猜测问题所在)。我想知道的是,如果我的问题已解决这一事实是在堆上声明此 char 缓冲区的某种奇怪结果,或者问题实际上是我的程序用完了堆栈内存。

我的计算机中有 6GB 的 RAM,并且在运行时,据我所知,没有其他程序会使用足够的内存来导致此问题。

【问题讨论】:

  • 可能duplicate
  • 谁调用 bufferAsInt ?下一个怎么称呼?
  • 即使您有 6GB 的 RAM,堆栈也可能只有几 MB。

标签: c++ memory heap-memory stack-memory


【解决方案1】:

你差了一个。

atoi 需要一个以 null 结尾的字符串。所以一个三位数的数字需要char[4] 才能正确存储。此外,read 不会在末尾添加 null。

试试这个:

void bufferAsInt(ifstream &inf, int &i)
{
    char peek[4];
    inf.read(peek, 3);
    peek[3] = 0;
    i = atoi(peek);
}

【讨论】:

  • 是的,看起来我们几乎在同一时间看到了它。
【解决方案2】:

atoi() 需要一个 C“NUL 终止的字符串”作为输入,即 ASCII 字符后跟一个 ASCII 零字节。这是函数知道在哪里停止转换的唯一方法。

在您的第一个代码清单中,您将三个字节读入一个三字节缓冲区,但您无法控制内存中的后续字节。我相信这是 C++ 中未定义的行为,所以实际上任何事情都可能发生。但是,通常情况下,如果后面的字节恰好是零或非数字,则字符串将正确转换;如果它碰巧是一个数字,你会得到一个不同的数字。

正确的解决方法是使用您的第一个示例,但是:

char peek[4];      // 4 char buffer instead of 3
inf.read(peek, 3);
peek[3] = '\0';    // ensure the 4th char is zero
i = atoi(peek);

【讨论】:

    【解决方案3】:

    很可能唯一改变的是new 与您的编译器和选项一起将数组归零。

    保证你会写

    char *peek = new char[3]();
    

    但是动态分配没有任何作用,所以改为这样:

    char peek[3] = {};
    

    注意:如果文件包含 3 位数字,则应改为使用 位数组,以便有空间终止零。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-30
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多