數據結構逆向分析-Vector
這個應該是家喻戶曉了的東西把,如果說C/C++程序員Vector都不用的話,可能就是一個不太好的程序員。
Vector就是一個STL封裝的動態數組,數組大家都知道是通過連續的地址空間來處理的,vector的原理就是如果原來的不夠了要擴展,就會開辟一段更大的內存,然后將原來的內容再復制到新的內存里面,釋放掉原來的,然后再插入要擴充的。
Vector常用Api:
push_bak() //尾部插入數據
Insert() //插入數據
pop_back() //刪除尾部數據
erase() //刪除數據
逆向分析:
插入數據
尾部插入
首先是最簡單的,一直往里面插入數據
一個只創建了的vector的大小只有16
然后通過內存來查看:
指向的這個地址:
又指回去了。
畫個圖就是這個樣子:
跑第一條插入數據的指令:
MyVector.push_back(100);
內存變成了這樣:
這個vector指向的內容還是沒有改變。
然后新加入了三個挨着的地址:
目前的情況來看,應該是vector的第二個內容是數組的首地址,然后第三第四個內容是數組的結束地址。
執行:
MyVector.push_back(600);
變成了這樣:
比較奇怪的是,如果是后面兩個字段表示數組的結束地址,為什么會要兩個字段來存放,一個就夠了呀,肯定有問題,所以我這里多push幾個,且觀察這兩個字段有沒有值不一樣的情況出現。
當執行完第五個push_back的時候終於變化了:
查看一下我們這個MyVector的數據結構:
capacity是指不再分配內存的情況下容器的容量,然后size是指容器當前存放了的大小。再對比我們在內存中的情況,那么很有可能就是size就是第三個字段地址減去第二個字段數組首地址,然后除以結構體大小得到的內容,而capacity容器大小就是最后一個字段和第二個字段數組首地址之間的差值。
再往下執行一個看看:
MyVector.push_back(150);
破案了,就是我們想的那樣,vector會開辟一段空間,然后往里面加內容,如果超過了容器大小再重新開辟一個。
任意位置插入數據:
紅色表示數據改動過,其實就是相當於往后移動,然后再插入進去,就是正常C語言里面會有的動態數組的操作。
刪除數據
尾部刪除
這里你會發現,用尾刪除的辦法來說,並沒有刪除掉這塊地址,只是把范圍往上移動了。
任意位置刪除:
這里也沒有刪除,只是把后面往前移動了,然后vector的數組大小又縮小:
實質數組大小和容器大小是不一樣的
總結