我正在尝试使用libconfig为我的程序创建配置文件。有两种情况,一种可以完美起作用(本地范围对象),另一个可以通过失败(全局范围对象)。我试图理解为什么一个人在另一个成功时失败,因为我的理解是两者都是创建相同对象的定义(仅在不同的范围中)。
1st(不起作用):我在全局范围中定义了配置对象。然后,我在配置对象上调用ReadFile。该程序在这里崩溃。
#include <libconfig.h++>
libconfig::Config cfg;
int __attribute__((constructor)) Init()
{
cfg.readFile("/home/jalius/csgo-internal/hack.cfg");
}
第二(工作):我定义了本地配置对象并在其上调用readfile。
#include <libconfig.h++>
int __attribute__((constructor)) Init()
{
libconfig::Config cfg;
cfg.readFile("/home/jalius/csgo-internal/hack.cfg");
}
当时在调用int __attribute__((constructor)) Init()
函数时,在您的情况下,cfg
对象不是创建。因为未指定使用属性constructor
和具有静态存储持续时间的C 对象的呼叫功能的顺序。由于对象不存在,因此您会收到分割故障错误,即SIGSEGV
信号。
以下是GCC网站的摘录:
目前,未指定使用静态存储持续时间和具有属性
constructor
功能的C 对象的构造函数。在混合声明中,属性init_priority
可用于施加特定的订单。
有关更多信息,请参见此页面上的constructor
部分。
无法保证您的函数int __attribute__((constructor)) Init()
在构建 Config
对象之前将被称为。
当您尝试从中读取它时,实际上可能尝试访问未构造的对象。这将导致不确定的行为。
当您在本地创建它时,可以保证您的对象在使用之前将完全初始化。
实验:
#include <iostream>
enum {
OBJECT_CONSTRUCTOR,
FUNCTION_CONSTRUCTOR,
};
int order[10], cur = 0;
class TestClass {
public:
TestClass() { order[cur++] = OBJECT_CONSTRUCTOR; }
~TestClass() { }
};
TestClass abc;
int __attribute__((constructor)) Init() {
order[cur++] = FUNCTION_CONSTRUCTOR;
}
int main ()
{
std::cout << "Order of execution:n";
for(int i = 0; i < cur; i++)
{
switch(order[i])
{
case OBJECT_CONSTRUCTOR:
std::cout<<"Object Constructorn";
break;
case FUNCTION_CONSTRUCTOR:
std::cout<<"Function Constructorn";
break;
}
}
return 0;
}
结果:
Order of execution:
Function Constructor
Object Constructor