简体   繁体   English

当我没有释放任何 memory 时,为什么 Memory 博士报告已释放 memory 错误?

[英]Why is Dr Memory reporting freed memory errors when I haven't freed any memory?

The following code以下代码

#include <vector>
#include <string>
#include <iostream>

struct Type
{
    std::string a;
};

int main()
{
    std::vector<unsigned char> data;

    data.resize(sizeof(Type));

    Type* a = new (&data[0]) Type({"something"});

    data.resize(sizeof(Type)*2);

    Type* b = new (&data[sizeof(Type)]) Type({"else"});

    Type* ts = reinterpret_cast<Type*>(&data[0]);

    for(std::size_t i = 0; i < 2; ++i)
    {
        std::cout << ts[i].a << std::endl;
        ts[i].~Type();
    }

    return 0;
}

produces this output from Dr Memory从 Memory 博士生产这个 output

Dr. Memory version 2.2.0 build 1 built on Jul  1 2019 00:42:20
Windows version: WinVer=105;Rel=1909;Build=18363;Edition=Enterprise
Dr. Memory results for pid 14664: "CPPTests.exe"
Application cmdline: "bin/Debug/CPPTests.exe -callstack_max_frames 40 -malloc_max_frames 40 -free_max_frames 40"
Recorded 117 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin\suppress-default.txt

Error #1: UNADDRESSABLE ACCESS of freed memory: reading 0x01750568-0x01750569 1 byte(s)
# 0 msvcrt.dll!_fwrite_nolock
# 1 msvcrt.dll!fwrite    
# 2 libstdc++-6.dll!?                +0x0      (0x6fe5cf56 <libstdc++-6.dll+0x1cf56>)
# 3 libstdc++-6.dll!?                +0x0      (0x6ff23d80 <libstdc++-6.dll+0xe3d80>)
# 4 _fu0___ZSt4cout                   [C:/tests.cpp:26]
# 5 __tmainCRTStartup                 [D:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:335]
# 6 KERNEL32.dll!BaseThreadInitThunk +0x18     (0x75306359 <KERNEL32.dll+0x16359>)
Note: @0:00:00.608 in thread 3732
Note: next higher malloc: 0x01750598-0x017505c8
Note: prev lower malloc:  0x01750468-0x0175046b
Note: 0x01750568-0x01750569 overlaps memory 0x01750560-0x01750578 that was freed here:
Note: # 0 replace_operator_delete                              [d:\drmemory_package\common\alloc_replace.c:2975]
Note: # 1 __gnu_cxx::new_allocator<>::deallocate               [C:/MSYS2-32/mingw32/include/c++/10.1.0/ext/new_allocator.h:133]
Note: # 2 std::allocator_traits<>::deallocate                  [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/allocator.h:187]
Note: # 3 std::_Vector_base<>::_M_deallocate                   [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/stl_vector.h:354]
Note: # 4 std::vector<>::_M_default_append                     [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/vector.tcc:675]
Note: # 5 std::vector<>::resize                                [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/stl_vector.h:940]
Note: instruction: movsx  (%eax) -> %eax

Error #2: INVALID HEAP ARGUMENT to free 0x01750568
# 0 replace_operator_delete                                   [d:\drmemory_package\common\alloc_replace.c:2975]
# 1 __gnu_cxx::new_allocator<>::deallocate                    [C:/MSYS2-32/mingw32/include/c++/10.1.0/ext/new_allocator.h:133]
# 2 std::allocator_traits<>::deallocate                       [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/allocator.h:187]
# 3 std::__cxx11::basic_string<>::_M_destroy                  [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/basic_string.h:237]
# 4 std::__cxx11::basic_string<>::_M_dispose                  [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/basic_string.h:232]
# 5 std::__cxx11::basic_string<>::~basic_string               [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/basic_string.h:658]
# 6 Type::~Type                                               [C:/tests.cpp:5]
# 7 _fu0___ZSt4cout                                           [C:/tests.cpp:27]
# 8 __tmainCRTStartup                                         [D:/mingwbuild/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:335]
# 9 KERNEL32.dll!BaseThreadInitThunk                         +0x18     (0x75306359 <KERNEL32.dll+0x16359>)
Note: @0:00:00.743 in thread 3732
Note: next higher malloc: 0x01750598-0x017505c8
Note: prev lower malloc:  0x01750468-0x0175046b
Note: 0x01750568-0x01750568 overlaps memory 0x01750560-0x01750578 that was freed here:
Note: # 0 replace_operator_delete                              [d:\drmemory_package\common\alloc_replace.c:2975]
Note: # 1 __gnu_cxx::new_allocator<>::deallocate               [C:/MSYS2-32/mingw32/include/c++/10.1.0/ext/new_allocator.h:133]
Note: # 2 std::allocator_traits<>::deallocate                  [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/allocator.h:187]
Note: # 3 std::_Vector_base<>::_M_deallocate                   [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/stl_vector.h:354]
Note: # 4 std::vector<>::_M_default_append                     [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/vector.tcc:675]
Note: # 5 std::vector<>::resize                                [C:/MSYS2-32/mingw32/include/c++/10.1.0/bits/stl_vector.h:940]

===========================================================================
FINAL SUMMARY:

DUPLICATE ERROR COUNTS:

SUPPRESSIONS USED:

ERRORS FOUND:
      1 unique,     1 total unaddressable access(es)
      0 unique,     0 total uninitialized access(es)
      1 unique,     1 total invalid heap argument(s)
      0 unique,     0 total GDI usage error(s)
      0 unique,     0 total handle leak(s)
      0 unique,     0 total warning(s)
      0 unique,     0 total,      0 byte(s) of leak(s)
      0 unique,     0 total,      0 byte(s) of possible leak(s)
ERRORS IGNORED:
      1 potential error(s) (suspected false positives)
         (details: C:\AppData\Roaming\Dr. Memory\DrMemory-CPPTests.exe.14664.000\potential_errors.txt)
      3 unique,     9 total,    154 byte(s) of still-reachable allocation(s)
         (re-run with "-show_reachable" for details)
Details: C:\AppData\Roaming\Dr. Memory\DrMemory-CPPTests.exe.14664.000\results.txt

But I was of the impression that this was all fine as I am not keeping any pointers into the vector after it's resized.但我的印象是这一切都很好,因为在调整大小后我没有保留任何指向向量的指针。 What am I not understanding?我不明白什么?

when I haven't freed any memory?当我还没有释放任何 memory 时?

Sure you have.你当然有。 You (potentially) free memory right here:您(可能)在这里免费获得 memory:

 data.resize(sizeof(Type)*2);
 ts[i].~Type();
 } // closes main

The issue is that when the vector reallocates memory, it will copy the unsigned char elements elsewhere.问题是当向量重新分配 memory 时,它会将unsigned char元素复制到其他地方。 This doesn't work for the Type object created in that memory because Type is not trivially copyable.这不适用于在 memory 中创建的Type object,因为Type不可轻易复制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM