为什么删除堆分配的字节数组会导致堆损坏

Why is Deleting a Heap Allocated Byte Array Causing a Heap Corruption

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

这是一个带有 class 的文件,名为 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;
}
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 <= capacity).