Visual c++ 如何组合CString、CSimpleMap和CSimpleArray typedef-ATL::CSimpleMap\u-Map; ATL::CSimpleArray g_arrMaps; _地图; Add(WTL::CString(L“first”)、WTL::CString(L“second”); 添加(WTL::CString(L“first2”)、WTL::CString(L“second2”); g_arrMaps.Add(map); //另一张地图被破坏了 对于(int i=0;i

Visual c++ 如何组合CString、CSimpleMap和CSimpleArray typedef-ATL::CSimpleMap\u-Map; ATL::CSimpleArray g_arrMaps; _地图; Add(WTL::CString(L“first”)、WTL::CString(L“second”); 添加(WTL::CString(L“first2”)、WTL::CString(L“second2”); g_arrMaps.Add(map); //另一张地图被破坏了 对于(int i=0;i,visual-c++,atl,cstring,Visual C++,Atl,Cstring,您不能将具有非平凡复制构造函数的类型与简单ATL集合一起使用。这些集合使用calloc/\u recalloc来管理它们的内存,并且不需要正确复制元素。您不能将具有非平凡复制构造函数的类型与简单ATL集合一起使用。这些集合ctions使用calloc/\u recalloc来管理内存,而不必麻烦正确地复制元素。

您不能将具有非平凡复制构造函数的类型与简单ATL集合一起使用。这些集合使用
calloc
/
\u recalloc
来管理它们的内存,并且不需要正确复制元素。

您不能将具有非平凡复制构造函数的类型与简单ATL集合一起使用。这些集合ctions使用
calloc
/
\u recalloc
来管理内存,而不必麻烦正确地复制元素。

有一个编译器提供的复制构造函数,它只复制指向其内部缓冲区的指针。当您将映射添加到
CSimpleArray
时,两个映射实际上共享相同的数据结构。当一个超出范围并释放内存时,另一个也会变得无效。在您的情况下,您可能会幸运地访问已释放的
CSimpleMap
缓冲区,但该缓冲区包含
CString
s,一旦删除,它们就释放了内部缓冲区,即char数组

您可以做什么:

  • 避免使用
    CSimpleMap
    。它实际上执行串行查找,并且具有可怕的默认复制构造函数。请改用CAtlMap,因为它的复制构造函数是私有的,所以您会知道在编译时出错了
  • CSimpleArray
    包含指向映射的指针:
    CSimpleArray
    。这意味着您需要额外的内存管理,但这样可以避免缓冲区共享
  • 或者,您可以继承
    CSimpleMap
    CAtlMap
    ,并为其提供一个合适的副本构造函数

  • CSimpleMap
    有一个由编译器提供的复制构造函数,它只会将指针复制到它的内部缓冲区。当您向
    CSimpleArray
    添加一个映射时,两个映射实际上共享相同的数据结构。当一个映射超出范围并释放内存时,另一个映射也会变得无效。在在这种情况下,您可能会幸运地访问已经释放的
    CSimpleMap
    buffer,但该buffer包含
    CString
    s,一旦删除,它们就释放了内部缓冲区,即char数组

    您可以做什么:

  • 避免使用
    CSimpleMap
    。它实际上执行串行查找,并且具有可怕的默认复制构造函数。请改用CAtlMap,因为它的复制构造函数是私有的,所以您会知道在编译时出错了
  • CSimpleArray
    包含指向映射的指针:
    CSimpleArray
    。这意味着您需要额外的内存管理,但这样可以避免缓冲区共享
  • 或者,您可以继承
    CSimpleMap
    CAtlMap
    ,并为其提供一个合适的副本构造函数

  • 你有编译器错误吗?我希望没有。将返回值存储在WTL::CString中,而不是直接调用ATLTRACE,看它是否工作。你有编译器错误吗?我希望没有。将返回值存储在WTL::CString中,而不是直接调用ATLTRACE,看它是否工作。
    typedef ATL::CSimpleMap<WTL::CString,WTL::CString> _Map;
    ATL::CSimpleArray<_Map> g_arrMaps;
    _Map map;
    map.Add(WTL::CString(L"first"),WTL::CString(L"second"));
    map.Add(WTL::CString(L"first2"),WTL::CString(L"second2"));
    g_arrMaps.Add(map);
    
    //another place _Map has been destructed
    for(int i=0;i<g_arrMaps.GetSize();i++){
        _Map m=g_arrMaps[i];
        for(int y=0;y<m.GetSize();y++){
            ATLTRACE(m.GetKeyAt(y)); //error
        }
    }