2011-11-22 91 views
6

這是很牽強的,但下面的代碼「安全」(即保證不會造成分段錯誤):正在訪問std :: vector :: reserve safe之後的原始指針嗎?

std::vector<int> vec(1); // Ensures that &vec[0] is valid 
vec.reserve(100); 
memset(&vec[0], 0x123, sizeof(int)*100); // Safe? 

我意識到,這是醜陋的 - 我只是想知道,如果它是技術上安全, 不漂亮」。我想它唯一的用法可能是忽略存儲在給定索引之外的值。

注意! How can I get the address of the buffer allocated by vector::reserve()?涵蓋了相同的主題,但我更感興趣,如果這是安全並且如果有這樣做的陷阱。

編輯:原始代碼是錯的,用memset代替原來的memcpy

+1

好吧,這是如此醜陋,它傷害。你爲什麼這樣做?如果你真的需要,你不能簡單地使用一個數組嗎?在這個例子中,100是固定的,所以你可以在堆棧上使用數組而不需要刪除[] ing ... – Francesco

+2

「分段錯誤」是一個特定於平臺的事件。 C++語言沒有描述它是什麼。該語言只是說明是否定義了某些東西,如果是,則說明是做什麼的。 –

+1

我已經低估了這個問題,並不是因爲我認爲這是一個糟糕的問題,而是因爲你沒有花足夠的時間來確保你所問的是你想問的問題(原始代碼和當前版本中的代碼是相當的不同)。-2個代表點並不多,但應該提醒你在將來稍微小心點,因爲當你問別人花時間回答試圖幫助的時候,如果你稍後再重新提出問題,那麼這段時間會被浪費掉上。 –

回答

16

不,它不安全。

reserve()之後,向量保證不重新分配存儲器,直到達到capacity()

但是,該標準沒有說明矢量實現可以在size()capacity()之間進行存儲。也許它可以用於一些內部數據 - 誰知道?也許地址空間只是保留,並沒有映射到實際的RAM?

訪問[0..size)之外的元素是未定義的行爲。有可能是一些硬件檢查。

+0

爲了指出_why_而提高_why_這是一個糟糕的主意:保留的內存是UB,並且不能通過矢量「正式」使用,直到它已經被調整大小或調整爲「push」/「emplaced」爲止。 –

2

矢量重新分配無效現有指針,引用等儲備可以引發再分配(23.3.6.2,[vector.capacity]),但你最終重新分配後採取的第一個元素地址(在這種情況下根本不會發生,但除此之外)。所以我看到代碼沒有問題。

+0

更新我的問題,使用memset而不是'memcpy(我的例子不正確)。 – larsmoa

2

首先請注意,您的memset會將0x123截斷爲單個字節,並且寫入的不是寫入4字節的模式。

然後,不這樣做,只是用容器:std::vector<int> vec(100, whatever_value_you_want);

但是回答這個問題,可能會出現專門爲POD類型的工作,如果編譯器不使用所分配的空間,任何的問題。當然,如果有人打電話給resize,insert,push_back等,它會吹走你已經寫入內存的任何東西,而且矢量的大小也是錯誤的。沒有理由寫這樣的代碼。

相關問題