【问题标题】:Why is Deleting a Heap Allocated Byte Array Causing a Heap Corruption为什么删除堆分配的字节数组会导致堆损坏
【发布时间】:2021-06-16 10:14:27
【问题描述】:

我正在尝试创建类似于堆栈的东西,但它是堆分配的。但是,当程序试图退出时,它说检测到堆损坏。我正在使用 Visual Studio 2019。

这是一个文件,其中包含一个名为 vstack 的类,它使用堆分配的字节数组:

#pragma once
#include<iostream>
#include<string>
#include<vector>

typedef unsigned char BYTE;
typedef BYTE* STACK;

struct VARIABLE {
    std::string name;
    int location = 0;
    char type = 0;
};


class Vstack {
    STACK vstack = nullptr;
    int stack_top = 0, capacity = 0;
    std::vector<VARIABLE> variables;

    //resizes the byte array
    void ReAlloc(size_t NewSize) {
        STACK NewData = new BYTE[NewSize];

        for (int i = 0; i != stack_top; i++)
            NewData[i] = vstack[i];

        delete[] vstack;
        vstack = NewData;
        capacity = NewSize;
    }

public:

    Vstack() {
        ReAlloc(2);
    }

    //create a long long int stored on the vstack
    void Create(std::string name, long long int value) {
        if (stack_top + sizeof(long long int) >= capacity)
            ReAlloc(capacity * 2);

        VARIABLE var;
        var.name = name;
        var.location = stack_top;
        variables.push_back(var);
        *(long long int*)(vstack + stack_top) = value;
        stack_top += sizeof(long long int);
    }


    //gets a pointer to a variable with the given name
    void* Read(std::string name) {
        for (int i = 0; i != variables.size(); i++)
            if (variables[i].name == name)
                return (vstack + variables[i].location);
        return nullptr;
    }

    ~Vstack() {
        delete[] vstack;
    }
};

这里是主文件:

#include<iostream>
#include"Vstack.h"

int main() {
    Vstack stack;
    stack.Create("x", 15);
    std::cout << *(long long int*)stack.Read("x") << std::endl;
}

【问题讨论】:

  • 不是造成它,而是在检测它。您在其他地方损坏了它,可能是由于运行不足或超出了数组边界。
  • 调试器和/或静态内存分析器应该会发现内存损坏。

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


【解决方案1】:
int main() {
  Vstack stack;

此时,stack.capacity 为 2,来自默认构造函数。

  stack.Create("x", 15);

此时stack.capacity已经翻倍到了4,而你刚刚写了一个long long,保证至少8字节。因此,您只是覆盖了缓冲区的末尾。

也许你需要更多容量而不是if,你应该检查while 你需要更多容量。或者您可以选择保证足够容量的操作(将容量加倍不会,但加倍然后添加sizeof(long long int) 会)。

使用assert 可以更轻松地检测到类似情况。你可以在Create()末尾增加stack_top后,assert(stack_top &lt;= capacity)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 2019-10-23
    • 2015-09-30
    相关资源
    最近更新 更多