2016-12-19 268 views
2

試圖接收一個具有未知大值的向量我想出了一個我認爲完全錯誤的解決方案:我認爲當std::vector<size_t>的一個元素首先被分配給一個小值,然後被分配給一個大的元素時可能會出錯或數據丟失,因爲整個矢量的類型已經設置好,並且內存中的一些空間被排列。使用不同整數類型的std :: vector <size_t>總是安全嗎?

然而,下面的代碼工作:

#include<vector> 
#include<iostream> 
#include<typeinfo> 

int main(){ 

    std::vector<size_t> vec; 

    // Fixing size and adding small number which 
    // I suppose would set type as a small one, 
    // i.e. int 
    vec.resize(2); 
    int i = 0; 
    std::fill(vec.begin(),vec.end(),i);  

    // add a big number that should not fit smaller type 
    unsigned long long bignum = 18446744073709551614; 
    vec.push_back(bignum); 

    std::cout<<vec[0]<<" "<<vec[1]<<" "<<vec[2]<<std::endl; 
    std::cout<<typeid(vec[0]).name()<<std::endl 
    <<typeid(vec[1]).name()<<std::endl<<typeid(vec[2]).name()<<std::endl; 

    // cell 0 was already initialized with int, trying to make oveflow 
    vec[0] = 18446744073709551613; 

    std::cout<<vec[0]<<" "<<vec[1]<<" "<<vec[2]<<std::endl; 
    std::cout<<typeid(vec[0]).name()<<std::endl 
    <<typeid(vec[1]).name()<<std::endl<<typeid(vec[2]).name()<<std::endl; 

    return 1; 
} 

但是,輸出不包含也許是因爲我的編譯器的類型名稱,:

$ ./a.out 
0 0 18446744073709551614 
m 
m 
m 
18446744073709551613 0 18446744073709551614 
m 
m 
m 

因此,它是適合所有的編譯器和可我當我不知道使用的整數類型時,可以自由地使用vector::<size_t>(發送給函數等)。

+0

應該是安全的。 size_t實際上是uint32_t或uint64_t,或者甚至uint16_t取決於目標機器體系結構。 –

回答

3

vector<size_t>表示條目全部爲size_t的向量。如果您嘗試存儲的值不是size_t,則在存儲之前它將被隱式轉換爲size_t。如果原始值是[0,SIZE_MAX]範圍之外的整數,則可能會導致數據丟失。

你的問題表明你想象的矢量存儲各種不同類型的對象,但是這不會發生。

注意:size_t通常代表最大可能的可分配單位的大小。也許最好使用更能反映你存儲的價值來源的類型,例如uint64_t

+0

謝謝!看起來我只是誤解了一切,因爲我認爲:_ size_t類型是無符號整數類型,它是sizeof運算符(和offsetof運算符)的結果,所以它保證足夠大以包含您的系統可以處理的最大對象的大小(例如,8Gb的靜態數組)。 size_t類型可能大於,等於或小於unsigned int,並且編譯器可能會爲優化做出假設。「_表示size_t調整變量大小以包含結果,但它只是一個鍵入 – Slowpoke

+1

@Slowpoke我看不到如何從引用的文本中獲得「size_t adjsts variable size」*不同的系統*可能具有不同的size_t大小,但在程序運行期間不會更改 –

+0

是的,對不起,一段時間以前,我的確誤解了這一點,並認爲sizeof是以某種方式應用於變量來包含數據。 – Slowpoke

3

不,這不安全。

這是唯一的工作,因爲你把int >= 0size_tunsigned所以如果你試圖把負值,你將有negative_value % 2**n其中n是用來表示無符號類型的位數。


向量中的元素是size_t。當您填寫i時,您可以要求編譯器將int轉換爲size_t。這不是「安全」的。


vec[0] = 18446744073709551613; 

在這裏,這是安全的,因爲VEC [0]是一個size_t


當心size_t被設計來處理...大小。所以可以處理size_t的最大值不是固定的。如果你想要股票整數。使用<cstdint>

+0

把一個負值賦給unsigned int不會有未定義的行爲。 –

+0

@DUJiaen我的不好,我以爲它就像C一樣。但它也不「安全」。 – Stargateur

3

除了@Stargateur的回答,最好的便攜式賭注是intmax_tuintmax_t。它們保證是平臺上可用的最大整數類型。

也可能有編譯器特定的擴展名,例如__int128_tThis answer給出了一些有關gcc中128位內建函數的信息。請注意,std::intmax_t將是64位。

+0

gcc通常提供'intmax_t'爲64位,'int128_t'爲128位整數類型(不符合標準) –

+0

@MM,OP沒有指定編譯器,但是謝謝,我會添加一個註釋有可能是編譯器特定的擴展 – Incomputable

相關問題