访问冲突将元素插入全局地图[重复]

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::iterator indx; mapAttributetable=GetAttributeTable(); indx=AttributeTable.find("attribute1"); 该问题由 jww 提出的解决方案的变体解决,该变体也类似于参考解决方案中的解决方案。无论 map 和 initialize 例程是在同一个文件中还是在不同的文件中,似乎都存在初始化问题。感谢大家的回复。

以上是关于访问冲突将元素插入全局地图[重复]的主要内容,如果未能解决你的问题,请参考以下文章

重复造轮子系列--桶排序

在javascript中访问全局数据-*属性[重复]

Postgres - 冲突 - 如何知道是不是发生了更新而不是插入 [重复]

将元素插入数组[重复]

将元素插入数组中间[重复]

将数据插入 ms 访问 [重复]