访问冲突将元素插入全局地图[重复]
Posted
技术标签:
【中文标题】访问冲突将元素插入全局地图[重复]【英文标题】:Access violation inserting element into global map [duplicate] 【发布时间】:2014-09-15 21:40:03 【问题描述】:我正在返回一个在大约 4 年后可以正常工作的 C++ 应用程序。我的第一个任务是将其从 Windows XP/.NET Framework 3.5/Win32/VS2008 更新到 Windows 7/.NET Framework 4.5/Win64/VS2012。
程序有一个全局映射声明,现在它在第一次尝试插入元素时收到访问冲突,而之前它运行正常。我在这里查看了所有相关参考资料,但找不到解决方案,因此我将不胜感激。代码如下所示:
Attributes.h:
static void LoadAttributes(void);
Attributes.cpp:
#include "sys\types.h"
#include <map>
static map<string,int> AttributeTable;
void LoadAttributes(void)
AttributeTable.insert(pair<string,int>("attribute1",1));
AttributeTable.insert(pair<string,int>("attribute2",2));
...
一旦它执行第一次插入,它就会产生访问冲突。这看起来像是一个初始化问题,因为智能感知显示了地图的地址,但未定义 _Right
和 _Left
指针:(_Right=?????, _Left=?????)
。
在方法中本地声明的映射具有这些值。我读过,如果静态映射和初始化它的静态方法在不同的文件中,那么初始化的顺序不能保证,但它们都在同一个文件中。
编辑——为了回应 jww,Dennis Chong 等人。正如我上面提到的,这个问题被标记为重复的问题涉及映射和初始化它的方法在 2 个不同的 cpp 文件中定义的情况。我了解在这种情况下无法保证订单。然而,解决方案指出,当两者在同一个 cpp 文件中时,初始化的顺序很好理解,并且应该是声明项目的顺序。由于这个原因,在我看来问题是不同的。
【问题讨论】:
听起来像 static initialization order fiasco。只是避免类类型全局变量。考虑使用 Meyers 单例而不是直接变量。 如果LoadAttributes()
被其他全局构造函数调用,那么初始化顺序将是不确定的。您可以先将地图设为静态变量 inside LoadAttributes
,然后看看会发生什么。
无关:我是唯一一个觉得奇怪的人static void LoadAttributes(void);
在 header 文件中吗?声明为static
,LoadAttributes 对当前翻译单元是本地的,因此除非 Attributes.cpp 被 #include
-ed 到其他一些 .cpp 文件中(这将是可怕的),标题中的声明似乎毫无意义且没有根据(而且一点儿也不臭)。
@WhozCraig:我只是没看到。经常发生。我(或一个人)没有看到完全出乎意料的情况。有一个关于这个的旧 SciAm 视频,一个穿着大猩猩服装的男人在一些专注于球赛的人中间跳华尔兹舞。他们没有注意到他。
对不起,我记错了,是那些专注于计算球传球的观众没有注意到(意外的)大猩猩。视频:youtube.com/watch?v=vJG698U2Mvo
【参考方案1】:
改变这个:
static map<string,int> AttributeTable;
void LoadAttributes(void)
AttributeTable.insert(pair<string,int>("attribute1",1));
AttributeTable.insert(pair<string,int>("attribute2",2));
...
收件人:
map<string,int>& GetAttributeTable()
static map<string,int> AttributeTable;
return AttributeTable;
void LoadAttributes(void)
map<string,int>& AttributeTable = GetAttributeTable();
AttributeTable.insert(pair<string,int>("attribute1",1));
AttributeTable.insert(pair<string,int>("attribute2",2));
...
【讨论】:
这个答案假设了一个可能的具体原因,但绝不是肯定的。然而,这是一个很好的第一步。如果它解决了问题,那很好;如果不是,则排除了一种可能性。 @Cheers -_Right=?????, _Left=?????
放弃它。但你是对的 - Visual Studio 非常随和,通常不会遇到这个问题。 Apple 是最不适应的,静态全局变量(甚至访问器)肯定会出现问题。对于 Apple,请参阅 Specify construction/destruction order of static locals in different accessors。
这解决了 void LoadAttributes(void) 问题。但是,现在,在我引用地图的任何地方,我都必须再次调用 GetAttributeTable(),它会返回一个空地图,例如,即使 LoadAttributes 终止时有 339 个条目,以下内容也会返回 0 索引:
map以上是关于访问冲突将元素插入全局地图[重复]的主要内容,如果未能解决你的问题,请参考以下文章