關於C 中vector的兩個小tips分享

2022-10-03 23:48:12 字數 1756 閱讀 4847

前言

本來這篇文章標題我想起成《關於 vector 的兩個小坑》,後來想想,其實也不算是坑,還是自己對原理性的東西理解的沒做那麼透徹。工作中遇到的很多問題,後來歸根到底都是基礎不牢靠。

vector 擴容

這個問題很經典了,但還是不小心踩到。有乙個需求是要對目標元素進行複製,而目標元素集合是儲存在 vector 裡面,於是簡單思考下就有如下**(大致含義):

void duplidate(vector* element_list, element* element)

void process()

}}看起來好像沒什麼問題,就是當前的 package 物件是否滿足複製的要求,需要的話,就對 package 的成員 owww.cppcns.comrigin_element 進行複製。跑 ut 也正常,然後在測試的時候就 coredump 了。看 mbgjtcore 檔案就是掛在了複製的時候。這裡我一開始就沒明白,乙個簡單的複製為什麼會有 coredump。

檢查了很久 element 複製的場景,甚至想要專門寫乙個拷貝建構函式。最後才恍然大悟, origin_element 指標指向的就是 element_list 裡面的元素, element_list 是整體流程的資料來源, packge 物件是封裝的中間處理物件。之前的開發人員為了方便,直接在 package 物件上儲存了原始的 element 指標,而這個指標指向的是乙個 vector 裡的元素。而我新加的邏輯會往原始的 vector 裡面再新增元素,那麼就有可能導致 vector 擴容,而 vector 擴容會導致整體的複製,從而導致原來指向這些元素的指標都失效了,靠後的 package 物件再去訪問 origin_element 就產生了 coredump。

當然,從設計上來說,就不應該儲存指向 vector 元素的指標,但是這裡有太多舊**牽涉,這裡就不做討論。

vector::erase()

起因是我在**裡面新增了如下**(大致):

void eraseelement(const vector::iterator& element_iter,

vector& element_list)

}然後 cr 的同學提出了乙個疑問是 element_iter 是 const 不可變的,但是在函式裡有擦除了對應的元素,這裡會不會有問題?雖然 ut 都已經跑過了,但是這種寫法的確比較奇怪,於是就藉機學習了一下 vector::erase() 的實現原理跟用法。

erase(iterator) 的實現原理其實不會改變 iterator ,而是把後面的元素乙個個往前移動,相當於是 iterator 指向的元素本身發生了變化,所以可以用 const 來修飾這個 iterator 。但是這裡用 cosnt & 其實是沒有錯但是無用的修飾,除了容易讓人誤判之外,其實沒有什麼實際用途。我之前是為了修正 cpplint 才把reference 改成 const reference。

另外 erase 本身的確比較危險,主要還是 erase 的時候 iterator 本身沒發生變化,但是指向的元素變了,,在很多時候 iterator 會自然地指向下乙個元素,但是mbgjt由於這是未定義的行為,這裡面可能會有不可預期的地方,所以最終改成顯示的獲取返回重新賦值( erase() 會返回下乙個迭代器,但這一點常常被忽略),這樣就能保證安全性了。更安全更推薦的做法應該是使用 remove_if() 這裡就不展開講了。

void eraseelement(vector& element_list,

vector::iterator程式設計客棧 element_iter ) }總結

本文標題: 關於c++中vector的兩個小tips分享

本文位址:

C 兩個小技巧

從新新那裡學來的,記錄一下,感覺還挺不錯,哈哈 一。靈活的在注釋與 間轉換 注釋風格 code here 風格 code here 看一下兩者之間,相差什麼呢?只差乙個斜槓 也就是說,只要刪乙個斜槓,就可以把中間這段 注釋掉,增加乙個斜槓,就可以使中間這段 有效。在寫一些測試 時會比較有用。二。寫個...

C 兩個小技巧

從新新那裡學來的,記錄一下,感覺還挺不錯,哈哈 一。靈活的在注釋與 間轉換 注釋風格 code here 風格 code here 看一下兩者之間,相差什麼呢?只差乙個斜槓 也就是說,只要刪乙個斜槓,就可以把中間這段 注釋掉,增加乙個斜槓,就可以使中間這段 有效。在寫一些測試 時會比較有用。二。寫個...

關於sqlmap的兩個小坑

i春秋作家 lsa 0x00 概述 近日在利用sqlmap注入測試時遇到乙個奇怪的現象,高版本sqlmap無法檢測出注入,但是低版本的可以測出注入,並且能跑出資料不是誤報,經過對比測試和檢視sqlmap原始碼,發現兩個小坑。0x01 情景重現 注入點形式 json whereparams 可注入引數...