在全局映射中插入元素时发生访问冲突
Access violation when inserting element into global map
我已经试着调试了好几个小时了,但没有成功。我知道你们会在几分钟内解决问题,所以情况如下:
我有大约400.cpp/.h文件,名为ProbemX.cpp/ProbemX.h(其中X是从1到400的数字)。每个文件都包含一个数学相关问题的解决方案。我想让这些问题在编译时用一个唯一的键(只需要一个int就可以了)将自己注册到一个全局映射中,并将该值作为启动数学问题解决方案的函数的指针。
全局映射是在名为Probem.h/Probem.cpp的文件中创建和处理的。然而,当第一个问题试图在映射中自我注册时,我收到了"读取位置0x00000004的访问冲突"。代码如下:
在ProblemX.h文件中(problem1启动了该问题的解决方案):
#ifndef PROBLEM1_H
#define PROBLEM1_H
#include "Problems.h"
#include <string>
std::string problem1();
static int rc1 = registerProblem(1, problem1);
#endif
在Problems.h文件中(problemFinder是使用全局映射来调用适当函数指针的函数):
#ifndef PROBLEMS_H
#define PROBLEMS_H
#include <string>
int registerProblem(int problemNum, std::string (*problemFunc)(void));
std::string problemFinder(int problemNum);
#endif
在Problems.pp:
#include "Problems.h"
#include <iostream>
#include <map>
using namespace std;
map<int,std::string (*)(void)> problems_map;
int registerProblem(int problemNum, string (*problemFunc)(void)) {
int rc = 0;
problems_map[problemNum] = problemFunc;
return rc;
}
string problemFinder(int problemNum) {
string retStr = "";
retStr = problems_map[problemNum]();
return retStr;
}
访问冲突发生在"problems_map[problemNum]=problemFunc;"处。
谢谢!
正如神秘命名的user93353所回答的那样,problems_map
全局变量不能保证在其他文件中的全局变量之前构造。
为了避免静态初始化顺序的失败,请将problems_map
设置为本地静态,它将在第一次使用时初始化:
map<int,std::string (*)(void)>&
get_problems_map()
{
static map<int,std::string (*)(void)> problems_map;
return problems_map;
}
然后像这样使用:
get_problems_map()[problemNum] = problemFunc;
这可以确保映射在需要时立即创建,而不仅仅是在Problems.cpp
的全局构造函数运行时,也就是在全局rc1
变量初始化后(在您的情况下肯定是这样)。
小心使用这样的静态它们的定义顺序可能会有所不同。变量可能存在,但不一定是构造的。这件事昨天真的咬了我一口,所以我记忆犹新。
在Problems.cpp
中,事物的定义顺序为:
static int rc1 = registerProblem(1, problem1);
map<int,std::string (*)(void)> problems_map;
这意味着rc1
在problems_map
之前被初始化。
因此,您的问题出现了,因为registerProblem
被调用来初始化rc1
,并且它使用了尚未构建的problems_map
。
我一直以为编译器会解决这个问题。但仔细想想,一般情况很难考虑(尤其是当你最终产生相互依赖关系时)。因此,我认为唯一明智的做法是期望程序员按照正确的顺序放置静态定义,就像他们应该对任何其他代码语句所做的那样。
查看构造函数上的C++常见问题解答。特别检查问题10.14至10.18-"静态初始化顺序失败"。
什么是"静态初始化顺序惨败"?
一种使程序崩溃的微妙方法。
静态初始化顺序的失败是一个非常微妙和常见的被误解的C++方面。不幸的是,很难发现--错误通常发生在main()开始之前。
简而言之,假设您有两个静态对象x和y,它们存在于单独的源文件,比如x.cpp和y.cppy对象的初始化(通常是y对象的构造函数)调用x对象上的某个方法。
就这样,就这么简单。
- 使用不带参数的函数访问结构元素
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- 从C++中的对列表中访问特定元素
- C++尝试深度复制唯一指针时出现内存访问冲突
- C++ 中动态二维数组的访问冲突
- 如何从静态向量访问类元素?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 写入访问冲突异常
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 从二进制文件中读取元素时引发异常(引发异常:读取访问冲突. _Pnext 0xB414D4)
- C++:向量元素赋值导致访问冲突
- 在全局映射中插入元素时发生访问冲突
- c++返回元素在没有代码的行上给出访问冲突
- 在全局映射中插入元素时发生访问冲突
- 设置数组元素时MSVC访问冲突
- 给map vector容器的元素赋值时发生访问冲突