static_casting 中等数量的 T* 到 void* 时访问冲突

Posted

技术标签:

【中文标题】static_casting 中等数量的 T* 到 void* 时访问冲突【英文标题】:Access violation when static_casting a mid-sized number of T* to void* 【发布时间】:2014-05-20 03:22:12 【问题描述】:

所以在休息了一段时间后,我一直在 C++ 中闲逛。我正在尝试将一个动态映射类组合在一起,该类将 std::string 映射到任何对象类型。根据 C++ 标准 static_casting 指向和来自 void* 的指针保留地址。因此,如果我将给定类型静态转换为 void 指针来存储它,并将它静态转换回原始类型的指针,我应该不会有任何问题。这是该课程的相关内容:

template<class T>
T& get( const std::string& key ) 

    return *static_cast<T*>( _data[ key ] );   


template < typename T >
void put( const std::string& key, const T& val ) 

    T* typePointer = new T( val );       
    _data[ key ] = static_cast<void*>( typePointer );         


std::map< std::string, void* > _data;

对于非指针参数,这些方法都可以正常工作,我想看看与静态类型 std::map 相比的 put/get 开销。但是,当向其中插入大量对象时,我会收到“访问冲突读取位置”错误。

// this works
DynamicMap myMap1;    
for (uint i=0; i<100; i++) 

    myMap1.put( "mat"+i, MyClass() );


// this doesn't
DynamicMap myMap2;
for (uint i=0; i<100000; i++) 

    myMap2.put( "mat"+i, MyClass() );

自从我接触 C++ 以来已经有几个月了,所以我对 VS2012 的异常感到生疏。我不明白为什么在向地图中插入大量数字时会发生这种情况...在它生成异常之前的数字在调试模式和发布之间发生变化。

【问题讨论】:

我猜myMap1.set 会是myMap1.putmyMap2 也一样 【参考方案1】:

warning: adding 'int' to a string does not append to the string

您的"mat"+i 不会创建一个新字符串,并在末尾附加i,因此您最终会弄乱密钥。使用"mat" + std::to_string(i) (C++11),或者

stringstream ss;
ss << i;
string i_string = ss.str();
myMap2.set( "mat"+i_string, MyClass() );    

【讨论】:

以上是关于static_casting 中等数量的 T* 到 void* 时访问冲突的主要内容,如果未能解决你的问题,请参考以下文章

使 .natvis 将 SmartPointer<T> 显示为 static_cast<T*>(void*)

static_cast<T>(-1) 是在没有 numeric_limits 的情况下生成全一位数据的正确方法吗?

leetcode 547. Number of Provinces 省份数量(中等)

C++ TBB concurrent_unordered_map find() at() return static_cast<size_t>( t ) * internal::hash_multip

leetcode中等781森林中的兔子

leetcode 二叉树的完全性检验 中等