gpt4 book ai didi

c++ - move 语义、奇怪的重复模板模式和内存泄漏

转载 作者:行者123 更新时间:2023-11-28 05:45:15 27 4
gpt4 key购买 nike

我已经实现了奇怪的重复模板模式的变体:

#include "stdafx.h"

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>

template<typename T>
struct Indexed
{
private:
static int s_maxIndex;
static std::map<int, T> s_map;

int m_index;
void SetNewIndex () { m_index = ++s_maxIndex; }

protected:
Indexed (T&& t)
{
SetNewIndex ();
s_map.insert (std::pair<int, T> (m_index, std::move (t)));
}

T& GetMappedRef () { return s_map[m_index]; }
static T& GetMappedRef (int index) { return s_map[index]; }

public:
int GetIndex () const { return m_index; }
static std::map<int, Indexed> const& GetAll () { return s_map; }
static void Clear () { s_map.clear (); }
};

template<typename T>
int Indexed<T>::s_maxIndex = 0;

template<typename T>
std::map<int, T> Indexed<T>::s_map;

struct MyObj
{
int m_myData;
MyObj () = default;
MyObj (int data)
:m_myData (data)
{
}
};

struct MyObjHandler : public Indexed<MyObj>
{
MyObjHandler (int value)
:Indexed (MyObj (value))
{
}

MyObj& GetObjRef ()
{
return GetMappedRef ();
}

static MyObj& GetObjRef (int index)
{
return GetMappedRef (index);
}
};

void test ()
{
MyObjHandler objH1 (4), objH2 (5);
std::cout << objH1.GetIndex () << ", " << objH2.GetIndex () << std::endl;
std::cout << objH1.GetObjRef().m_myData << ", " << objH2.GetObjRef().m_myData << std::endl;
}

int _tmain (int argc, _TCHAR* argv[])
{
test ();

_CrtDumpMemoryLeaks ();

system ("pause");
return 0;
}

以下是使用“MyObjHandler”而不是“MyObj”的两个示例:

  1. 表示一个图,其中每个节点都关联到“MyObj”的一个实例。我们在每个图节点存储一个索引,并使用全局映射来获取“MyObj”的相应实例。
  2. 在范围内创建“MyObj”的实例会使该实例在范围末尾超出范围:

    void CreateObj (){

    我的对象;

    //对obj的操作;

    }//obj 超出范围

但我想保留该实例以备后用。因此,我需要利用 move 语义的力量。

它似乎可以工作,但它会导致内存泄漏:

Detected memory leaks!

Dumping objects ->

{216} normal block at 0x0063D1A0, 24 bytes long. Data: < c H c c

A8 D0 63 00 48 D1 63 00 A8 D0 63 00 00 00 CD CD

{215} 正常 block 位于 0x0063D148,24 字节长。数据:

A8 D0 63 00 A8 D0 63 00 A0 D1 63 00 01 00 CD CD

{214} 正常 block 位于 0x0063D100,8 字节长。数据:<@> 40 A3 14 01 00 00 00 00

{213} 正常 block 位于 0x0063D0A8,24 字节长。数据:

48 D1 63 00 48 D1 63 00 A0 D1 63 00 01 01 CD CD

对象转储完成。

为什么?

最佳答案

我觉得很正常。您可以尝试注释对 test 函数的调用,内存泄漏仍然存在(较小,但仍然存在)。

在我看来,_CrtDumpMemoryLeaks 错误地将静态映射识别为内存泄漏 - 它是在程序开始时分配的,并且仍在使用中。此行为与指定的一致 here :

When an unfreed block is encountered, _CrtDumpMemoryLeaks calls _CrtMemDumpAllObjectsSince to dump information for all the objects allocated in the heap from the start of program execution.

如果你注释掉静态映射,内存泄漏就没有了。

关于c++ - move 语义、奇怪的重复模板模式和内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36358398/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com