C++ Visual Studio C++&引用;ProjectName.exe已触发断点";以及其他问题
我已经研究过这个问题,但我还没有得到一个好的答案,所以我想我应该在这里问一下C++ Visual Studio C++&引用;ProjectName.exe已触发断点";以及其他问题,c++,visual-studio,C++,Visual Studio,我已经研究过这个问题,但我还没有得到一个好的答案,所以我想我应该在这里问一下 我正在研究C++中的一个项目,它涉及到一点内存操作(分配动态字符数组并使用放置新的方法将内存地址和完整对象放在这些数组中)。p> 每次在Visual Studio中调试程序时,我都会遇到一个非常令人沮丧的问题:通常会弹出一条消息,说“ProjectName.exe已触发断点”。有时会说“在2-Kennel.exe中的0x0FFD66CB(ucrtbased.dll)抛出异常:0xC0000005:访问冲突读取位置0xf
我正在研究C++中的一个项目,它涉及到一点内存操作(分配动态字符数组并使用放置新的方法将内存地址和完整对象放在这些数组中)。p> 每次在Visual Studio中调试程序时,我都会遇到一个非常令人沮丧的问题:通常会弹出一条消息,说“ProjectName.exe已触发断点”。有时会说“在2-Kennel.exe中的0x0FFD66CB(ucrtbased.dll)抛出异常:0xC0000005:访问冲突读取位置0xfffff5。”
下面是相关类的代码 h类\ifndef CAT#H
#定义类别H
#包括
#包括“犬舍h”
使用std::string;
班猫{
私人:
静态狗窝;
内部id;
字符串\u名称;
Cat(int i、const string和nm):\u name(nm){//注意初始值设定项列表
_id=i;
}
void*运算符新(大小\u t大小){
返回catKennel.allocate();
}
公众:
静态Cat*create(int-id、const-string和name){//Factory方法
返回新的Cat(id、名称);
}
void运算符删除(void*loc){
猫舍解除分配(loc);
}
};
狗窝猫:狗窝(5只);
#恩迪夫
犬舍
#ifndef KENNEL_H
#define KENNEL_H
#include <cstddef>
#include <cassert>
#include <iostream>
#include <new>
class Kennel {
private:
static const size_t _BUCKET_COUNT = 10;
const size_t _BUCKET_SIZE;
const size_t _ELEM_SIZE;
char* buckets[_BUCKET_COUNT];
//char** buckets;
char* availableBlock;
public:
Kennel(size_t elemSize, size_t bucketSize = 5);
~Kennel();
void* allocate(); // Get a pointer inside a pre-allocated block for a new object
void deallocate(void*); // Free an object's slot (push the address on the "free list")
};
#endif
\ifndef犬舍
#定义犬舍
#包括
#包括
#包括
#包括
等级犬舍{
私人:
静态const size\u t\u BUCKET\u COUNT=10;
const size\u t\u BUCKET\u size;
常量大小元素大小;
字符*BUCKET[_BUCKET_COUNT];
//炭**桶;
字符*可用的块;
公众:
犬舍(尺寸电气化,尺寸bucketSize=5);
~Kennel();
void*allocate();//在为新对象预先分配的块内获取指针
void deallocate(void*);//释放对象的插槽(将地址推到“空闲列表”上)
};
#恩迪夫
犬舍
#include "Kennel.h"
Kennel::Kennel(size_t elemSize, size_t bucketSize) : _ELEM_SIZE(elemSize), _BUCKET_SIZE(bucketSize) {
//Set each element in buckets to nullptr.
for (int i = 0; i < _BUCKET_COUNT; i++)
buckets[i] = nullptr;
}
Kennel::~Kennel() {
//Delete each character array in buckets.
for (int i = 0; i < _BUCKET_COUNT; i++) {
if (buckets[i] != nullptr)
delete[] buckets[i];
}
}
void* Kennel::allocate() {
//If there is no available bucket: create a new one.
if (availableBlock == nullptr) {
//Find next array index in buckets array where we can create a new bucket.
int nextNullBucketIndex = -1;
for (int i = 0; i < _BUCKET_COUNT; i++) {
if (buckets[i] == nullptr) {
nextNullBucketIndex = i;
break;
}
}
assert(nextNullBucketIndex > -1); //If there is no space to create another bucket: exit.
//Create a new bucket.
buckets[nextNullBucketIndex] = new char(_BUCKET_SIZE * _ELEM_SIZE);
availableBlock = buckets[nextNullBucketIndex];
char* tempBlock = availableBlock;
//Put the address of the next block inside each block.
std::cout << "Bucket " << nextNullBucketIndex << ": ";
for (int i = 0; i < _BUCKET_SIZE - 1; i++) {
std::cout << static_cast<void*>(tempBlock) << ' ';
new (tempBlock) char*(tempBlock += _ELEM_SIZE);
}
std::cout << static_cast<void*>(tempBlock) << std::endl;
new (tempBlock) char*(nullptr); //The last block doesn't get an address, put nullptr in it.
}
char* tempAvailable = availableBlock;
availableBlock = *reinterpret_cast<char**>(availableBlock);
std::cout << "Returning: " << static_cast<void*>(tempAvailable) << std::endl;
return static_cast<void*>(tempAvailable);
}
void Kennel::deallocate(void* loc) {
new (loc) char*(availableBlock); //Store availableBlock's contained address in loc.
availableBlock = static_cast<char*>(loc); //Set availableBlock's contained address to be loc's address.
}
#包括“Kennel.h”
犬舍:犬舍(大小电气化,大小木桶尺寸):\u电气化,大小木桶尺寸(木桶尺寸){
//将bucket中的每个元素设置为nullptr。
对于(int i=0;i<\u BUCKET\u COUNT;i++)
桶[i]=nullptr;
}
犬舍::~犬舍(){
//删除存储桶中的每个字符数组。
对于(int i=0;i<\u BUCKET\u COUNT;i++){
if(bucket[i]!=nullptr)
删除[]个桶[i];
}
}
void*犬舍::分配(){
//如果没有可用的bucket:创建一个新的bucket。
如果(availableBlock==nullptr){
//在bucket数组中查找下一个数组索引,我们可以在其中创建一个新bucket。
int-nextnullbuckettendex=-1;
对于(int i=0;i<\u BUCKET\u COUNT;i++){
if(bucket[i]==nullptr){
nextnullbuckettendex=i;
打破
}
}
assert(nextnullbuckettendex>-1);//如果没有空间创建另一个bucket:exit。
//创建一个新的bucket。
BUCKET[nextnullbuckettendex]=新字符(\u BUCKET\u SIZE*\u ELEM\u SIZE);
availableBlock=存储桶[nextNullBucketIndex];
char*tempBlock=availableBlock;
//将下一个块的地址放入每个块中。
标准::cout
这只分配一个char
,而不是它们的数组。然后,您继续将内容写入您不拥有的内存。std::string
也new
会占用相同的内存,然后您的堆会出错。如果您得到“ProjectName.exe已触发断点”,检查控制台,并检查可能位于其他窗口后面的对话框。当标准库检测到您出错时,它通常会显示一条消息,然后触发一个断点(当您不使用调试器时,这是一个崩溃)。我正式是一个傻瓜。我做了很多事情,只是忽略了每次阅读。
#include "Kennel.h"
Kennel::Kennel(size_t elemSize, size_t bucketSize) : _ELEM_SIZE(elemSize), _BUCKET_SIZE(bucketSize) {
//Set each element in buckets to nullptr.
for (int i = 0; i < _BUCKET_COUNT; i++)
buckets[i] = nullptr;
}
Kennel::~Kennel() {
//Delete each character array in buckets.
for (int i = 0; i < _BUCKET_COUNT; i++) {
if (buckets[i] != nullptr)
delete[] buckets[i];
}
}
void* Kennel::allocate() {
//If there is no available bucket: create a new one.
if (availableBlock == nullptr) {
//Find next array index in buckets array where we can create a new bucket.
int nextNullBucketIndex = -1;
for (int i = 0; i < _BUCKET_COUNT; i++) {
if (buckets[i] == nullptr) {
nextNullBucketIndex = i;
break;
}
}
assert(nextNullBucketIndex > -1); //If there is no space to create another bucket: exit.
//Create a new bucket.
buckets[nextNullBucketIndex] = new char(_BUCKET_SIZE * _ELEM_SIZE);
availableBlock = buckets[nextNullBucketIndex];
char* tempBlock = availableBlock;
//Put the address of the next block inside each block.
std::cout << "Bucket " << nextNullBucketIndex << ": ";
for (int i = 0; i < _BUCKET_SIZE - 1; i++) {
std::cout << static_cast<void*>(tempBlock) << ' ';
new (tempBlock) char*(tempBlock += _ELEM_SIZE);
}
std::cout << static_cast<void*>(tempBlock) << std::endl;
new (tempBlock) char*(nullptr); //The last block doesn't get an address, put nullptr in it.
}
char* tempAvailable = availableBlock;
availableBlock = *reinterpret_cast<char**>(availableBlock);
std::cout << "Returning: " << static_cast<void*>(tempAvailable) << std::endl;
return static_cast<void*>(tempAvailable);
}
void Kennel::deallocate(void* loc) {
new (loc) char*(availableBlock); //Store availableBlock's contained address in loc.
availableBlock = static_cast<char*>(loc); //Set availableBlock's contained address to be loc's address.
}
std::cout << "Returning: " << static_cast<void*>(tempAvailable) << std::endl;
buckets[nextNullBucketIndex] = new char(_BUCKET_SIZE * _ELEM_SIZE);