为什么Visual Studio在已删除的指针位置显示内存泄漏?

时间:2019-07-28 20:21:48

标签: c++ visual-studio pointers memory-leaks

我目前正在出于教学目的创建玩具语言,并且最近检查了我的代码是否存在内存泄漏;但是,在Visual Studio中,我的代码中的随机位置似乎存在内存泄漏,这些内存泄漏不会使用“ new”在堆上分配任何内容。不仅如此,它还说我在调试打印要删除的内存位置丢失了60个字节。

我的语言是用抽象语法树设置的,该树概括了某些表达式和语句。在这些语句的每一个中,都有一个destroy方法,该方法删除我拥有的所有其他Ast指针,并删除其任何子级。此方法消除并删除所有多余的指针。但是,在随机位置有随机内存泄漏,因为我确认已删除的一个或两个指针没有释放它们的内存。目前,我尝试将使用“ new”关键字分配的所有指针分配到一个指针数组中,并尝试释放所有指针,但是最终比我的原始清理方法泄漏更多。

这是当前的解析方法

void Parser::parse(VirtualMachine& vm) {
    while (curr().getType() != EOF_Token) {
        Ast* ast = parseStatement(vm, true);
        ast->parse();
        ast->destroy(); // This is the cleanup method
        vm.compile();
        std::cout << "DELETING: " << ast << std::endl;
        delete ast;
    }
    vm.clear();
}

主要方法如下:

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

try {
    auto t1 = std::chrono::high_resolution_clock::now();
    ace::Parser parser(file, lines);
    parser.parse(parser.vm);
    auto t2 = std::chrono::high_resolution_clock::now();
    std::cout << "took "
        << std::chrono::duration_cast<std::chrono::milliseconds>(t2 
  t1).count()
<< "ms\n";
}
catch(std::exception&) {
        return EXIT_FAILURE;
}

destroy方法的示例如下所示(BinaryAst):

void destroy() override {
        // Destroying other object's children if they are also a BinaryAst
    left->destroy();
    right->destroy();
        // Debug Print
    std::cout << "DELETING: " << left << std::endl;
    std::cout << "DELETING: " << right << std::endl;
        // Deleting the current ast's children
    delete left;
    delete right; // This one is deleted but still has the memory leak
    left = nullptr;
    right = nullptr;
}

这是解析语句方法。它将隐式返回该结构的子级。

Ast* Parser::parseStatement(VirtualMachine& vm, bool flag) {
    if (curr().getType() == EOF_Token)
        return nullptr;
    else if (curr().getToken() == "var" || curr().getToken() == "let") 
        return parseVariableAssignment(vm);
    else if (curr().getType() == LCurlyBrace) 
        return parseBlock(vm, flag);
    else if (curr().getToken() == "print")
        return parsePrintStatement(vm);
    else if (curr().getToken() == "input")
        return parseInputStatement(vm);
    else if (curr().getType() != EOF_Token && peek(1).getToken() == "=") 
        return parseVariableReassignment(vm);
    else if (curr().getToken() == "if") 
        return parseIfStatement(vm, false);
    else if (curr().getToken() == "while")
        return parseWhileStatement(vm);
    else {
        auto expression = parseExpression(vm);
        if (expression == nullptr) {
            auto current = curr();
            Error::unexpectedToken(current, lines[curr().getLine() - 1]);
        }
        return expression;
    }
    return nullptr;
}

我在这里设置了调试标志,以告诉我任何错误。对于内存泄漏,我得到的输出如下:

Detected memory leaks!
Dumping objects ->

// Al the other 8 bytes point to the same random location which does not provide any allocation for pointers
{2855} normal block at 0x01326FC8, 8 bytes long.
 Data: < H2     > 98 48 32 01 00 00 00 00 

// This is the block of memory that I have freed but shows as leaking
{2854} normal block at 0x01324880, 60 bytes long.
 Data: <`(*  Q2 <$*     > 60 28 2A 00 C8 51 32 01 3C 24 2A 00 05 00 00 00 

{2211} normal block at 0x01325DB0, 8 bytes long.
 Data: < [1     > 80 5B 31 01 00 00 00 00 
{1747} normal block at 0x01326088, 8 bytes long.
 Data: < R2     > 90 52 32 01 00 00 00 00 
{1476} normal block at 0x01326F20, 8 bytes long.
 Data: <$R2     > 24 52 32 01 00 00 00 00 
{1167} normal block at 0x01326E78, 8 bytes long.
 Data: < H2     > 98 48 32 01 00 00 00 00 
{823} normal block at 0x013274D0, 8 bytes long.
 Data: < [1     > 80 5B 31 01 00 00 00 00 
Object dump complete.

所有其他块似乎都指向我的头文件中某些变量的声明的末尾,这些变量都没有使用new或指针进行分配。试图弄清内存泄漏是什么还是有点误导。

我期望输出是没有内存泄漏。我以为输出至少会显示没有泄漏的字节数,除了它向没有任何内存分配的位置显示的随机泄漏之外。

0 个答案:

没有答案