【问题标题】:Stack overflow with no recursion?没有递归的堆栈溢出?
【发布时间】:2020-12-16 14:26:34
【问题描述】:

据我所知,我的代码没有递归,但出现异常 0xC00000FD。根据 Rider For Unreal Engine 的说法,它发生在 main 函数中。在反编译的代码中遇到了

mov byte ptr [r11], 0x0

它工作正常,然后当我第二次运行它时,为了确保它正常工作,它突然坏了。现在它每次都会给出这个例外。 这是我的代码:

// Language.cpp
#include <fstream>
#include <iostream>
#include <regex>
#include <stdexcept>
#include <string>


#include "Lexer/Lexer.h"
#include "Util/StrUtil.h"

int main(int argc, char* argv[])
{
    std::string line, fileString;
    std::ifstream file;
    file.open(argv[1]);
    
    if(file.is_open())
    {
        int lines = 0;
        
        while(file.good())
        {
            if (lines > 10000)
            {
                std::cerr << "Whoa there, that file's a little long! Try compiling something less than 10,000 lines." << '\n';
                return -1;
            }
            getline(file, line);
            fileString += line + (char)10;
            lines++;
        }
    }

    fileString += (char)0x00;

    std::string arr[10000];
    int arrLength = StrUtil::split(fileString, "\n", arr);

    Line lines[10000];
    Lexer::lex(arr, arrLength, lines);
    
    return 0;
}
// Lexer.cpp
#include "Lexer.h"

void Lexer::lex(std::string (&str)[10000], int length, Line (&lines)[10000])
{
    for (int i = 0; i < length; i++)
    {
        
    }
}
// StrUtil.cpp
#include "StrUtil.h"


#include <stdexcept>
#include <string>

int StrUtil::split(std::string str, std::string delimiter, std::string (&out)[10000])
{
    int pos = 0;
    out[0] = str;
    while (out[pos].find(delimiter) != std::string::npos)
    {
        const size_t found = out[pos].find(delimiter);
        out[pos + 1] = out[pos].substr(found + delimiter.length());
        out[pos] = out[pos].substr(0, found);
        pos++;
    }

    return pos + 2;
}

对于自定义类型,LineTokens 的数组,它们只是 TokenType, std::string> 对。

【问题讨论】:

  • std::string arr[10000];Line lines[10000]; -- 堆栈爆炸了。
  • @PaulMcKenzie 你的意思是内存不足吗?
  • @LysanderMealy 除了堆栈内存不足之外,什么是堆栈溢出?
  • @LysanderMealy 我想是时候学习使用std::vector了,
  • 顺便提一下,(char)0x00 通常写成'\0'。而(char)10 是不寻常的;如果应该插入换行符,请将其写为'\n'

标签: c++ lexer


【解决方案1】:

据我所知,我的代码没有递归

确实,所示代码中没有递归。缺少递归并不意味着你不会溢出堆栈。

没有递归的堆栈溢出?

是的,这个程序可能会在某些系统上溢出堆栈。

std::string arr[10000];

std::string 的典型大小为 32 字节(在不同的语言实现之间可能会有很大差异)。 10000 个字符串是 312 kiB。大多数桌面系统上的执行堆栈是一到几 MiB。这个数组大约是程序最深堆栈帧中必须容纳所有自动变量的内存的三分之一。剩余的堆栈内存不足以供程序的其余部分使用是非常可行的,特别是考虑到您还有另一个庞大的 Line 对象数组。

要修复程序,请不要在自动存储中分配诸如此类的大量变量。

【讨论】:

    猜你喜欢
    • 2018-03-25
    • 2012-07-08
    • 2015-04-04
    • 2017-01-20
    • 2018-12-02
    • 2017-09-06
    • 2019-07-08
    • 2015-08-05
    • 2017-09-29
    相关资源
    最近更新 更多