我正在使用Visual Leak Detector来检测内存泄漏,并且在以下行中遇到了许多内存泄漏事件:
class SomeClass
{
// ...
std::map<long,long> some_map;
void func(long a_long, long b_long)
{
some_map[a_long] = b_long; // here be a memory leak
}
}
Run Code Online (Sandbox Code Playgroud)
这怎么可能呢?这里没有指针,没有对象实例化.
这可能是内存泄漏是由于其他原因导致程序崩溃的副作用吗?程序崩溃或退出(1)会导致地图不被彻底破坏吗?
我有一个类模板,打算使用其参数K作为地图的关键.
有没有办法将模板参数限制为符合std :: map中的Key的类型?
我意识到,即使没有这样的约束,编译器也会吐出一堆模板错误,比如K没有operator < (),但如果我能在指定需求时使代码更明显,那就更好了.
欢迎使用C++ 11解决方案.
template< typename K >
class Foo
{
// lots of other code here...
private:
std::map< K, size_t > m_map;
};
Run Code Online (Sandbox Code Playgroud) 此方法导致中止错误:"map/set iterator not incrementable."
由于在if失败之后并且确定应该擦除的虚拟迭代器(并且是),继续到映射中的下一个迭代器++_iter失败,因为_iter它不再是有效的对象/指针.
迭代地图的正确程序是什么,并且能够在整个过程中删除单个项目?
typedef std::map<std::string, BITMAP*> MapStrBmp;
typedef MapStrBmp::iterator MapStrBmpIter;
\\...
void BitmapCache::CleanCache() {
//Clean the cache of any NULL bitmaps that were deleted by caller.
for(MapStrBmpIter _iter = _cache.begin(); _iter != _cache.end(); ++_iter) {
if(_iter->second != NULL) {
if((_iter->second->w < 0 && _iter->second->h < 0) == false) continue;
}
_cache.erase(_iter);
}
}
Run Code Online (Sandbox Code Playgroud) 我的项目中有一张地图.每次插入新元素时,我都希望确保插入的新元素的键至少是地图中其他元素的最小宽度.为此,我写了一个自定义比较类,如下所示:
class PulseCompare
{
public:
PulseCompare(int minwidth_):minwidth(minwidth_){};
bool operator()(const int x, const int y) const {
if(abs(x-y)>minwidth) return false;
else return true;
}
private:
int minwidth;
};
Run Code Online (Sandbox Code Playgroud)
并创建了这样的地图:
std::map<int,float,PulseCompare> pulsemap(PulseCompare(256));
Run Code Online (Sandbox Code Playgroud)
在我插入元素之前,我使用如下map.find方法:
if ( pulsemap.find(1600) == pulsemap.end() ) {
// not found so I can insert
} else {
// found
}
Run Code Online (Sandbox Code Playgroud)
但问题是,当图试图反射性地使用上述通过互换的价值比较功能x和y,就得到true了两种情况通常是不正常的比较操作等的情况<和>
在std::map::key_comp 这里的cplusplus文档页面上它说,我引用
在构造上设置地图对象的比较对象.其类型(成员key_compare)是地图模板的第三个模板参数.默认情况下,这是一个较小的对象,它返回与运算符"<"相同的对象.
此对象确定容器中元素的顺序:它是一个函数指针或一个函数对象,它接受与元素键相同类型的两个参数,如果第一个参数被认为是在第二个参数之前,则返回true.它定义的严格弱排序,否则为假.
如果key_comp以反射方式返回false,则认为两个键是等效的(即,无论键作为参数传递的顺序如何).
但这并没有说明它是反射性的情况true.谁能告诉我它的行为会是什么呢?或者我应该只通过迭代整个地图来进行间隔比较?
字典定义如下:
typedef boost::tuple<conn_ptr, handler_ptr, rdp_ptr> conn_tuple;
typedef std::map<GUID, conn_tuple> conn_map;
Run Code Online (Sandbox Code Playgroud)
我们遇到了编译错误:
错误9错误C2678:二进制'<':找不到运算符,它接受类型为'const GUID'的左手操作数(或者没有可接受的转换)c:\ program files(x86)\ microsoft visual studio 11.0\vc \包括\ xstddef
然后我们解决它:
struct GUIDComparer
{
bool operator()(const GUID & Left, const GUID & Right) const
{
// comparison logic goes here
if( (Left.Data1 == Right.Data1) && (Left.Data2 == Right.Data2) &&
(Left.Data3 == Right.Data3) && (memcmp(Left.Data4 , Right.Data4,sizeof(Right.Data4))==0) )
{
return true;
}
return false;
}
};
typedef boost::tuple<conn_ptr, handler_ptr, rdp_ptr> conn_tuple;
typedef std::map<GUID, conn_tuple, GUIDComparer> conn_map;
Run Code Online (Sandbox Code Playgroud)
现在,所有编译,但然后我们在运行时得到一个异常(无效的运算符<).
我不知道出了什么问题,如果有人可以提供帮助,我会很高兴
我发现自己经常处于编写以下代码的情况:
std::map<int, std::vector<int>> dict;
void insert(int key, int val) {
if (dict.find(key) == dict.end()) {
dict[key] = std::vector<int>();
}
dict[key].push_back(val)
}
Run Code Online (Sandbox Code Playgroud)
编写这个插入函数是否有一种不那么冗长的方式(在C++ 11中)?
我试着用:
std::map<std::wstring, std::pair<std::wstring, INT_PTR>> mm;
**mm.insert(_T("name"), std::make_pair(_T("value1"), static_cast<INT_PTR>(1));**
Run Code Online (Sandbox Code Playgroud)
这有什么问题?
如果我用这个:
mm[_T("name")] = std::make_pair(_T("value1"), static_cast<INT_PTR>(1));
Run Code Online (Sandbox Code Playgroud)
有用.
错误是这样的:
No constructor could take the source type, or constructor overload resolution was ambiguous
Run Code Online (Sandbox Code Playgroud)
与此相同:
std::map<std::wstring, std::vector<std::pair<std::wstring, INT_PTR>>> mm;
std::vector <std::pair<std::wstring, INT_PTR>> vec;
vec.push_back(std::make_pair(_T("value1"), static_cast<INT_PTR>(1)));
mm.insert(_T("name"), vec);
Run Code Online (Sandbox Code Playgroud)
为什么它可以像这样使用"insert_or_assign"?
mm.insert_or_assign(_T("name"), vec);
Run Code Online (Sandbox Code Playgroud) 是否有透明的std::unique_ptr容器使用方式?
#include <iostream>
#include <memory>
#include <map>
struct method {
virtual ~method() { std::cout << "f\n"; };
};
typedef std::unique_ptr<method> MPTR;
std::map<int, MPTR> tbl;
void insert(int id, method *m) {
tbl.insert({id,std::unique_ptr<method>(m)});
};
void set(int id, method *m) {
tbl[id] = std::unique_ptr<method>(m);
};
int main(int argc, char **argv) {
insert(1,new method());
set(1,new method());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想使用tbl.insert({id,m});和tbl[id] = m;等,而不必为每次访问包装/解包.
std::map.Following is my code for creating a map<int, vector<int>> and printing:
//map<int, vector>
map<int, vector<int>> int_vector;
vector<int> vec;
vec.push_back(2);
vec.push_back(5);
vec.push_back(7);
int_vector.insert(make_pair(1, vec));
vec.clear();
if (!vec.empty())
{
cout << "error:";
return -1;
}
vec.push_back(1);
vec.push_back(3);
vec.push_back(6);
int_vector.insert(make_pair(2, vec));
//print the map
map<int, vector<int>>::iterator itr;
cout << "\n The map int_vector is: \n";
for (itr2 = int_vector.begin(); itr != int_vector.end(); ++itr)
{
cout << "\t " << itr->first << "\t" << itr->second << "\n";
}
cout << endl;
Run Code Online (Sandbox Code Playgroud)
The printing part …
当我编译(g++ -std=c++14 map.cpp)并运行该程序时,它似乎没有终止。谁能解释为什么?但是,当我确实找到('a')而不是'c'时,它给出了零。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
map<char, float> m;
m['a'] = 3.4;
m['b'] = 5.3;
m['c'] = 33.3;
m['d'] = 43.;
auto it = m.find( 'c' );
cout << "distance : " << std::distance( it , m.begin() ) << endl;
}
Run Code Online (Sandbox Code Playgroud)