[英]C++ Segmentation Fault when using cout in static variable initialization
我有一個程序,我使用cout發出調試信息。 代碼在靜態全局變量的初始化中執行,即在程序執行的早期。 當我使用自己的構建腳本來構建程序時,它首次使用cout時會出現段錯誤(只有字符串文字被轉移到cout中,所以它不能是值)。 我使用valgrind檢查早期寫入無效位置,但沒有(並且也沒有可能生成這些寫入的代碼,我在輸出之前不做太多)。 當我將源代碼復制到eclipse項目並讓eclipse內置構建器構建它時,一切正常。 我沒有使用簡單的編譯器設置,只使用-ggdb -std=c++0x
編譯,這些是唯一的兩個標志。
那么,如果之前沒有無效的寫入,那么帶有字符串文字段錯誤的cout可能是什么原因? 構建配置如何影響這個?
(對不起,我不能給你一個最小的例子,因為這個例子可以簡單地在你的機器上編譯,就像在使用eclipse構建器時那樣)
編輯:這是堆棧跟蹤:
0x00007ffff7b6d7d1 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib /x86_64-linux-gnu/libstdc++.so.6
(gdb) backtrace
#0 0x00007ffff7b6d7d1 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x00007ffff7b6dee9 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff7b6e2ef in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00000000004021be inTest::fill (this=0x6120f8, funcs=...) at inTest.cpp:92
最后一幀是我的代碼。 第92行簡單地寫道:
std::cout << "Test";
std::cout
是靜態存儲中的對象。 它保證在進入main
之前初始化,但不一定在代碼中的其他靜態之前初始化。 看起來像靜態初始化命令fiasco。
經過一番挖掘:
Init ();
3)效果:構造類Init的對象。 如果init_cnt為零,則函數將值1存儲在init_-cnt中,然后構造並初始化對象cin,cout,cerr,clog(27.3.1),wcin,wcout,wcerr和wclog(27.3.2)。 在任何情況下,函數然后將一個值添加到存儲在init_cnt中的值。
正如Luchian指出的那樣,在構造ios_base::Init
的第一個實例之前,不能使用std::cout
。 但是,您不必定義實例; 包括<iostream>
應該足夠了。
初始化的順序是一個翻譯單元中定義的。 如果在所有具有靜態實例的文件的頂部包含<iostream>
,則應該沒問題。 但是,如果靜態對象的構造函數調用另一個轉換單元中的函數,並且輸出位於該轉換單元中,則僅在執行輸出的轉換單元中包含<iostream>
是不夠的。 您必須將其包含在定義靜態變量的轉換單元中。 即使他們沒有做任何輸出。
靜態變量初始化是一個無人區。 如果你避免在那里做大量工作,你將避免問題。 也許你應該將靜態變量包裝成Singleton模式,這樣你就可以在第一次使用時將初始化推遲。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.