C++堆损坏,但仅在单元测试项目中
C++ Heap Corruption but only in Unit Test Project
我正在使用模板实现一个自定义堆栈。但是我遇到了一个问题,让我质疑内存安全性。析构函数在正常使用时工作正常,但在单元测试时会触发堆损坏。特别是在预期引发异常的测试中。
所有堆栈代码。
#pragma once
#include "StackOverflowException.h"
#include "StackEmptyException.h"
template <class T>
class Stack
{
public:
const static int MAX_SIZE = 1000;
Stack() : m_array(new T[MAX_SIZE]), m_size(0), m_top(0) {};
Stack(const Stack<T>& _other)
{
m_array = new T[MAX_SIZE];
for(auto i = 0; i < _other.size(); ++i)
{
m_array[i] = _other.m_array[i];
}
m_size = _other.size();
m_top = _other.m_top;
}
~Stack()
{
delete[] m_array;
}
void push(T _item)
{
if (m_size + 1 == MAX_SIZE + 1)
{
throw StackOverflowException();
}
m_array[++m_top] = _item;
++m_size;
}
T pop()
{
if(m_top != 0)
{
--m_size;
T item = m_array[m_top];
--m_top;
return item;
}
throw StackEmptyException();
}
T peek() const
{
if (m_size == 0) throw StackEmptyException();
T item = m_array[m_top];
return item;
}
bool empty() const
{
return m_size == 0;
}
size_t size() const
{
return m_size;
}
private:
T* m_array;
size_t m_size;
int m_top;
};
导致堆损坏的单元测试。
TEST_METHOD(CustomStackPopException)
{
Stack<int> stack;
Assert::ExpectException<StackEmptyException>([&] { stack.pop(); });
}
TEST_METHOD(CustomStackPeekException)
{
Stack<int> stack;
Assert::ExpectException<StackEmptyException>([&] { int a = stack.peek(); });
}
TEST_METHOD(CustomStackOverflowException)
{
Stack<int> stack;
const auto functor = [&]
{
for(auto i = 0; i <= Stack<int>::MAX_SIZE; ++i)
{
stack.push(i);
}
};
Assert::ExpectException<StackOverflowException>(functor);
}
当它到达这些测试中的第一个时,它将抛出一个弹出警告,说:
HEAP CORRUPTION DETECTED: after Normal block(#279) at 0x0000020298CBC60.
CRT detected that the application wrote to memory after end of heap buffer.
我尝试在堆上创建堆栈对象,但这会导致相同的错误。
此成员函数
void push(T _item)
{
if (m_size + 1 == MAX_SIZE + 1)
{
throw StackOverflowException();
}
m_array[++m_top] = _item;
++m_size;
}
已经不正确了。假设 MAX_SIZE 等于 1,m_size 等于 0。在这种情况下,m_size + 1 不等于 MAX_SIZE + 1,并且有
m_array[1] = _item;
在分配的阵列之外。
编辑:按以下方式更改方法后
void push(T _item)
{
if (m_size + 1 > MAX_SIZE)
{
throw StackOverflowException();
}
m_array[++m_top] = _item;
++m_size;
}
在我指出它的问题之后,实际上该方法也有同样的问题。事实上,你什么也没做。
此外,您的堆栈不会用索引 0 填充项目。所以在构造函数中
Stack(const Stack<T>& _other)
{
m_array = new T[MAX_SIZE];
for(auto i = 0; i < _other.size(); ++i)
{
m_array[i] = _other.m_array[i];
}
m_size = _other.size();
m_top = _other.m_top;
}
在位置 0 处访问具有不确定值的项目
成员函数推送应该像这样定义
void push( const T &_item)
{
if (m_size == MAX_SIZE)
{
throw StackOverflowException();
}
m_array[m_top++] = _item;
++m_size;
}
其他成员功能应根据成员功能推送进行更改。
多亏了用户的组合,问题已经解决。是推送功能导致了错误。
推送功能已从:
void push(T _item)
{
if (m_size + 1 == MAX_SIZE + 1)
{
throw StackOverflowException();
}
m_array[++m_top] = _item;
++m_size;
}
自:
void push(T _item)
{
if (m_size == MAX_SIZE)
{
throw StackOverflowException();
}
m_array[m_size] = _item;
++m_size;
++m_top;
}
构造函数已从:
Stack() : m_array(new T[MAX_SIZE]), m_size(0), m_top(0) {};
自
Stack() : m_array(new T[MAX_SIZE]), m_size(0), m_top(-1) {};
现在大小和顶部不再相同,m_top
实际上指向堆栈的顶部。
使用分配编号
HEAP CORRUPTION DETECTED: after Normal block(#279) at 0x0000020298CBC60.
CRT detected that the application wrote to memory after end of heap buffer.
然后在启动插入的某个地方
_CrtSetBreakAlloc(279);
这将向您显示内存的分配位置,并应提供有关损坏位置的重要提示。
为什么要自己手卷?
不要自己实施stack
STL 已经有该容器
template <class T>
using my_stack = std::stack< T, std::vector<T> >;
相关文章:
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 如何将我的 CMake 项目配置为运行所有单元测试?
- C++堆损坏,但仅在单元测试项目中
- Visual Studio 2010 单元测试:无法识别引用的项目类
- 在Visual Studio本机单元测试中,是否可以将单元测试耦合到项目?
- 在单元测试项目中包括 .c 文件,并从多个 cpp 文件访问它而不会出现链接问题
- Catch2 单元测试未与 CMake 项目一起运行
- 单元测试类无法在我要测试的同一解决方案中的另一个项目中找到类
- 我的 Visual c++ 托管单元测试项目未读取输入文件
- C++单元测试项目 LoadLibrary 失败,出现"序号未找到"错误
- 对单元测试(googletest)和项目/文件夹/文件的混淆
- 使用 Boost 单元测试进行 G++ 项目编译
- 如何从.exe项目导入代码进行单元测试
- Visual studio单元测试静态库;防止主项目中的附加依赖项
- 设置单元测试需要多少个项目
- Visual Studio C++托管测试项目和本机单元测试项目之间的区别
- 如何在使用单个测试项目时将所有QtTestLib单元测试的结果组合在一个文件中?
- 从单元测试.EXE项目引用VC++.EXE项目中的类
- 在项目中使用QT单元测试-主(..)函数冲突
- 在VS.NET 2010中构建c++单元测试项目时链接错误