C++ std::fstream在使用预分配内存时在main之后崩溃
我目前在堆栈上创建了一个C++ std::fstream在使用预分配内存时在main之后崩溃,c++,memory,memory-management,C++,Memory,Memory Management,我目前在堆栈上创建了一个std::ofstream,当它分配一个全局操作符new从预先分配的缓冲区分配内存时,程序将在main完成引用std::locale0:第59行后崩溃。读取访问冲突。nodeptr被0x…作为程序崩溃点nodeptr的内存地址是实地址。我不知道为什么会发生这种情况,我只能假设这是因为我误解了分配的实际作用 此行为发生在版本在MSVC 19.10.25019 x86版上测试的构建上,构建在调试上,程序完成而不崩溃。Dr.Memory报告在调试模式下没有泄漏 最小代码: #i
std::ofstream
,当它分配一个全局操作符new
从预先分配的缓冲区分配内存时,程序将在main
完成引用std::locale0:第59行后崩溃。读取访问冲突。nodeptr被0x…
作为程序崩溃点nodeptr
的内存地址是实地址。我不知道为什么会发生这种情况,我只能假设这是因为我误解了分配的实际作用
此行为发生在版本
在MSVC 19.10.25019 x86版
上测试的构建上,构建在调试
上,程序完成而不崩溃。Dr.Memory报告在调试模式下没有泄漏
最小代码:
#include <fstream>
#include <cstdlib>
std::uint8_t *byte = static_cast<std::uint8_t*>(malloc(134217728)); // 134217728 = 128 MiB
void *operator new(size_t bytes) throw(std::bad_alloc)
{
return static_cast<void*>(byte); // Tested empirically, and this is only called once so this shouldnt be a cause of a problem
}
void operator delete(void *memory) throw()
{}
int main()
{
std::ofstream out("abc");
free(byte);
}
#包括
#包括
std::uint8_t*byte=static_cast(malloc(134217728));//134217728=128 MiB
void*运算符新(大小字节)抛出(std::bad\u alloc)
{
return static_cast(byte);//经过经验测试,只调用一次,所以这不应该是问题的原因
}
void操作符delete(void*内存)throw()
{}
int main()
{
标准:流出流(“abc”);
自由(字节);
}
有两个明显的错误:
运算符new
,该怎么办?如果out
的构造函数构造了一个子对象怎么办out
仍在范围内时,您可以释放字节
。当out
的析构函数运行时,您已经将其内存返回到系统#include <fstream>
#include <cstdlib>
std::uint8_t *byte = static_cast<std::uint8_t*>(malloc(134217728)); // 134217728 = 128 MiB
void *operator new(size_t bytes) throw(std::bad_alloc)
{
static int offset = 0;
void * ret = static_cast<void*>(byte + offset);
offset += 16 * ((bytes + 15) / 16);
return ret;
}
void operator delete(void *memory) throw()
{}
int main()
{
{
std::ofstream out("abc");
}
free(byte);
}
#包括
#包括
std::uint8_t*byte=static_cast(malloc(134217728));//134217728=128 MiB
void*运算符新(大小字节)抛出(std::bad\u alloc)
{
静态整数偏移=0;
void*ret=static_cast(字节+偏移量);
偏移量+=16*((字节+15)/16);
返回ret;
}
void操作符delete(void*内存)throw()
{}
int main()
{
{
标准:流出流(“abc”);
}
自由(字节);
}
与以前完全相同的例外情况。对于1)这是因为我想要尽可能最小的代码,我忘了解释我测试并确保只调用一次new
。(1) ,设置所有设备以使用流和其他启动程序可能涉及多个步骤allocations@M.M我的意思是永远不会给出相同的地址两次(除非分配大小为零),并对齐到16字节的边界。(这显然是我弄错了。)至少在Visual Studio 2017中,似乎没有在调试版本中调用替换的new。在发布版本中,只调用一次替换new,崩溃似乎是在清理与您的描述匹配的区域设置时发生的。代码中的注释讨论了如何销毁惰性方面。如果你在文件中看起来稍微高一点,你会发现在调试构建中,有一个新的C++类,它是一个关于自定义分配和STD::LoalALE的VisualC++错误。“CRT中的std::locale假设所有方面都在CRT堆上分配”-一个bug报告,该bug似乎与您遇到的问题不同。类似,但不确切。由于程序无论如何都会退出,因此不释放该块确实没有什么害处,因为它无论如何都会被清理,但泄漏检测器可能会抱怨。我总是想释放一切,即使我也要离开。