std :: fstream在使用预先分配的内存后主要崩溃

时间:2017-06-07 03:18:40

标签: c++ memory memory-management

我目前在堆栈上创建了std::ofstream,当它分配一个从预先分配的缓冲区分配内存的全局operator new时,程序将在main之后崩溃完成引用std::locale0 : line 59. Read Access Violation. nodeptr was 0x...作为程序崩溃点。 nodeptr的内存地址是一个真实的地址。我不知道为什么会这样,我只能假设这是因为我误解了分配实际上在做什么。

release上测试的MSVC Version 19.10.25019 x86版本上发生此行为,构建在debug上的程序已完成且没有崩溃。 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);
    }

2 个答案:

答案 0 :(得分:0)

有两个明显的错误:

  1. 如果多次调用operator new怎么办?如果out的构造函数构造子对象怎么办?

  2. byte仍在范围内时,您可以免费out。当out的析构函数运行时,您已经将其内存返回给系统。

  3. 试试这个:

    #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);
        }
    

答案 1 :(得分:0)