最近同事專案中遇到乙個問題,就是在main函式未啟動之前,就出現崩潰。具體現場情況大致是使用了乙個map,但這個map的insert操作直接導致崩潰。最終定位的原因,是map的定義是放到了另乙個編繹單元之中,而使用map的時候,該map物件還未進行初始化。這是全域性變數的初始化順序問題,即是用到某個變數的時候,它其實還未初始化。
知識點:
1、全域性變數的初始化,是在main函式之前。
2、不同編繹單元的全域性變數,初始化有先後順序之分。
下面看兩段**即可比較明確該問題
test1.cpp
#include
#include
using
namespace
std;
class
test1
};
test1 obj_test1;
test2.cpp
#include
#include
using
namespace
std;
class
test2
};
test2 test2;
int
main(
int
argc,
char
** argv)
makefile
target=main
objs=test1.o test2.o
$(target):$(objs)
g++ -o main test1.o test2.o
#g++ -o main test2.o test1.o
%.o:%.cpp
g++ -c $<
clean:
rm $(target) -f
rm $(objs) -f
注意最後的鏈結命令,這裡生成main的時候,即可以用g++ -o main test1.o test2.o,也可以使用g++ -o main test2.o test1.o,大多數情況下, 這樣對結果是沒有什麼區別。但在這個問題上,是有很大區別。
g++ -o main test1.o test2.o,這樣是test2這個類先構造 ,g++ -o main test2.o test1.o,這樣則是test1這位類先構造 。大家可以自行修改鏈結順序觀察初始化順序。
對於類的初始化過程,如果需要使用的其他類物件,是定義到其他編繹單元的時候,則可能遇到這種初始化順序的問題。一般來說,有如下幾種解決方案:
2、將變數定義到乙個編繹單元之中,這樣就直接規避了這個問題。如果實在無法用這種方式的時候,推薦使用第3種。
3、採用函式構造,不直接使用變數。通過主動觸發乙個函式返回乙個物件,在函式對主動觸發物件的構造,例如在函式中去new乙個物件出來。
static全域性變數 全域性變數
1 全域性變數 外部變數 的說明之前再冠以static 就構成了靜態的全域性變數。全域性變數本身就是靜態儲存方式,靜態全域性變數當然也是靜態儲存方式。這兩者在儲存方式上並無不同。這兩者的區別在於非靜態全域性變數的作用域是整個源程式,當乙個源程式由多個原始檔組成時,非靜態的全域性變數在各個原始檔中都是...
全域性變數的問題
今天在工程裡新增了乙個專門放置全域性變數的標頭檔案,在別的很多c檔案中進行了引用,沒想到編譯的時候老是提示duplicate symbal g7task.說來自己也太差勁了,竟然忘了在c檔案中新增extern關鍵字來引用這個外部變數。而且要命的是在標頭檔案中是不能賦初值的,否則會遇到同樣的鏈結錯誤。...
php 全域性變數問題
當在函式裡通過require once包含另外php檔案。而另外php檔案包含了另外php檔案,而該php檔案的函式需要另外的php檔案。例子 installment maintenance submit.php檔案裡downloadzip函式在內部包含了reboottipsfunc.php fun...