成员对象的地址在构造函数之后立即发生变化

The address of a member object is changing immediately after constructor

如果您想查看导致此问题的代码,可以在此处查看并克隆该项目:https://github.com/NickChapman/RuM/tree/63047e457745558403ea807534e4f5b9930cfeb8

值得注意的一点是在构造函数中我有(RuMParser.cpp 第 20 行):

this->globalScope = Scope();
std::cout << &(this->globalScope) << std::endl;

然后在构造函数完成后立即得到(RuM.cpp 第 63 行):

std::cout << &(this->parser.globalScope) << std::endl;

这些的输出是:

0x7fff57ac5318
0x7fff57ac6988

为什么它们不一样?对于所有剩余时间,地址将保持固定在第二个值。为什么在离开构造函数后它会发生变化?

我在第一次打印输出后立即尝试建立指针时注意到了这个问题。指针在构造函数完成后指向一个较旧的地址,我很困惑为什么。

我怀疑这与复制构造函数或类似性质的东西有关。

编辑:作为参考,如果您正在尝试构建源代码并且 运行 您可以:

cmake .
make

然后

./rum

输入x=1;$会导致程序出现段错误。

this->parser = RuMParser(tokenList);
std::cout << &(this->parser.globalScope) << std::endl;

首先,创建一个临时 RuMParser,这是您获得第一个打印件的时间。然后将临时文件复制构造成 this->parser。也就是说,globalScope 又是默认构造的。因此在后面的打印中地址不同。

好吧,代码中有很多 questionable/non-idiomatic 东西,但我只会坚持对这个问题重要的东西。您可以将构造函数重写为:

RuMInterpreter::RuMInterpreter(): 
      tokenList(std::make_shared<std::vector<Token>>())
     ,parser(tokenList) 
{
....
} 

只要有可能,总是优先使用成员初始值设定项列表。我猜它也是有效的 C++ 书中的项目之一。