在调用main()函数之前重置全局对象中的向量
vector in global object is reset before main() function invoked
以下是我的代码…
main.cpp
/* header files are included here */
PCI_card card;
int main(void)
{
card.init_card(0);
return 0;
}
pci_card.h
#ifndef __PCI_CARD_H
#define __PCI_CARD_H
/* header files are included here */
typedef struct {
int32_t card_index;
int32_t user_counter;
} card_dev_t;
class PCI_card {
public:
PCI_card() : dev_descriptor(-1) { enlarge_vector(); }
int32_t init_card(int32_t card_num);
private:
int32_t dev_descriptor;
public:
static int32_t enlarge_vector();
private:
static int32_t card_amount;
static std::vector<card_dev_t> cards;
};
#endif
pci_card.cpp
/* header files are included here */
int32_t PCI_card::card_amount = -1;
std::vector<card_dev_t> PCI_card::cards;
int32_t PCI_card::init_card(int32_t card_num)
{
if (card_num >= card_amount || card_num < 0)
return -1;
card_dev_t new_card = {
.card_index = card_num,
.user_counter = 1
};
cards[card_num] = new_card;
dev_descriptor = card_num;
return 0;
}
int32_t PCI_card::enlarge_vector()
{
card_amount = 10;
card_dev_t null_card = {
.card_index = -1,
.user_counter = -1
};
cards.resize(card_amount, null_card);
return card_amount;
}
在main.cpp中,card
被定义为全局变量,当然,在调用main()
函数之前应该对其进行初始化,这可以通过gdb清楚地看到。
初始化card
时,调用PCI_card
类的构造函数,根据card_amount
成员变量调整该类中的向量cards
的大小。从gdb中,这个向量被正确初始化,它包含10个元素。
在调用main()
函数之前发生了奇怪的事情,向量被重置。在gdb中,vector的大小回滚到0,当然,后续的操作,比如下标这个vector,会导致segment fault error。
我不知道这里发生了什么....这太荒谬了……
看起来您遇到了静态初始化顺序惨败。PCI_card card;
的初始化有可能发生在std::vector<card_dev_t> PCI_card::cards
之前。如果发生这种情况(并且标准允许),那么PCI_card::enlarge_vector()
将调用resize(这里输入UB)尚未初始化的向量。执行完PCI_card::cards
后,将执行正常的静态初始化——将vector初始化为空vector。这就是为什么你会看到这样的行为:
在gdb中,vector的大小回滚到0,
这是未定义行为,所以你在gdb中看到的任何东西都是可能的。
解决方案是将卡片设置为非静态的,或者使用带有静态字段的静态函数返回卡片:
std::vector<card_dev_t>& getCards() {
static std::vector<card_dev_t> cards;
return cards;
}
这将确保cards
在第一次使用getCards.
时被初始化
相关文章:
- 类的全局对象和静态成员
- 内存清理程序报告全局对象构造中未初始化值的使用
- 涉及全局对象的循环依赖C++
- C++本地/全局对象的初始化
- 何时调用全局对象的构造函数?
- 不可变的全局对象应该声明为"const my_result_t BLAH"还是"extern const my_result_t BLAH;"?
- C++全局对象丢失值
- std::atexit 从全局对象的构造函数调用时的排序
- 如果 LTO 中的代码依赖于其构造的副作用,是否允许 LTO 删除未使用的全局对象?
- 从全局对象构造函数停止监视器计时器
- 全局引用全局对象
- 是否保证在销毁所有线程本地存储对象后销毁全局对象
- 销毁全局对象
- 如何在线程之间共享全局对象
- 在QT GUI中创建一个全局对象
- 使用全局对象时崩溃,但使用本地对象时不会崩溃
- C 全局对象变量内存释放
- 如何在嵌入式V8中重置全局对象
- 如何创建可供src/code和lib/libraries访问的全局对象
- 强制构造全局对象