插入元素时访问冲突进入全球地图(Access violation when inserting el

2019-08-02 15:29发布

我一直在想,现在没有运气调试这几个小时。 我知道你们会解决分钟内的问题,所以这里的情况:

我有〜400的.cpp / .h文件名为ProblemX.cpp / ProblemX.h(其中X是从1到400)。 每个文件都包含了数学相关问题的解决方案。 我想有这些问题在编译时自己注册到一个独特的密钥的全球地图(只是一个int将工作),并具有值是一个指针揭开序幕数学问题的解决方案的功能。

全球地图的建立与所谓Problem.h / Problem.cpp文件处理。 然而,我发现了一个“访问冲突读取位置0x00000004”时,第一个问题试图在地图上自行注册。 代码如下:

在ProblemX.h文件(问题1揭开序幕这个问题的解决方案):

#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.cpp:

#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;”。

谢谢!

Answer 1:

由于神秘地命名user93353回答中, problems_map全球不能保证在其他文件中全局之前建造。

为了避免静态初始化顺序的悲剧,使problems_map 本地静态的,将在其第一次使用时init'd:

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变量被初始化。



Answer 2:

小心使用这样的静。 在定义它们可以有所作为的顺序。 变量可能是有,但它不一定构成。 这实际上昨天咬了我的屁股,所以这是记忆犹新。

Problems.cpp ,定义的顺序的事情之一是:

static int rc1 = registerProblem(1, problem1);
map<int,std::string (*)(void)> problems_map;

这意味着rc1之前初始化problems_map

因此,您的问题涉及有关,因为registerProblem被称为初始化rc1和它使用problems_map这尚未构成。

我一直以为,编译器会来解决这一问题。 但是,当你想想看,一般情况下是太困难的考虑(特别是如果你最终相互依赖)。 所以我想,唯一理智的事情是希望程序员把自己定义静以正确的顺序,就像他们应该与任何其他代码语句做。



Answer 3:

检查的C ++ FAQ 构造函数 。 特别是检查问题10.14 10.18 - “静态变量初始化顺序的悲剧”。

什么是“静态变量初始化顺序的悲剧”?

一个微妙的方式,你的程序崩溃。

静态初始化顺序的悲剧是C ++的一个非常微妙的并且常见的误解。 不幸的是这是防不胜防 - 错误之前的主经常发生()开始。

总之,假设您有两个静态对象x和y存在于不同的源文件,说x.cpp和y.cpp的。 进一步假设对于Y对象(通常在y对象的构造函数)的调用x对象的某些方法。

而已。 就这么简单。



文章来源: Access violation when inserting element into global map
标签: c++ map