網頁

2014年12月13日 星期六

C++ vector - Pointer or Not

Last Update: 2014/12/13 20:13+08
Type: Note



Intro

當我們宣告一個 vector 時, 要用 Pointer 還是 不要用 比較好?
我覺得是要看個人使用習慣
雖然有人說用 new 出來的, 也就是用 Pointer 比較好
但其實只要瞭解它的運作, 別搞亂就可以了
需要注意的是 vector 在 超出它當前的容納量時, 會重新 宣告/要求 分配memory




Content

看個簡單的例子
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <map>
class MyClass {
public:
 std::string id;
 float x, y, z;
};
int main(int argc, const char **argv) {

 std::vector list;
 list.reserve(2);

 list.push_back(MyClass());

 MyClass *p1 = &list[0];

 list.push_back(MyClass());
 list.push_back(MyClass());

 MyClass *p2 = &list[0];

 printf("%p, %p\n", p1, p2);

 return 0;
}

你會發現 明明都是指向 vector 的第零個元素, p1 和 p2 卻指向不同的address
reserve 主要就是要避免 頻繁的 重配 memory, 造成 runtime 的浪費
因此, 若我預留2個, push 第3個時, vector 會重配記憶體, 所以address也就不同了

C/C++ 就是經常用pointer的語言
咱們也常常儲存 pointer 來指向相關的class



so 解決的方法
1. 初始後 就不會再變更的大小, 可以不用pointer
std::vector list = std::vector(3);
2. 用map儲存其對應的id
std::vector<MyClass> list;
std::map<std::string, unsigned int> idMap;

MyClass item = MyClass();
item.id = "A";

list.push_back(item);
idMap[item.id] = list.size() - 1;
3. 乖乖用 new MyClass
int main(int argc, const char **argv) {

 std::vector list;
 list.reserve(2);

 list.push_back(new MyClass());

 MyClass *p1 = list[0];

 list.push_back(new MyClass());
 list.push_back(new MyClass());

 MyClass *p2 = list[0];

 printf("%p, %p\n", p1, p2);

 return 0;
}
但記得, 有 new 就要有 delete



Reference

C++ vector 與 memory


沒有留言:

張貼留言