wutiejun / CppStudy

Study notes for CPP.
0 stars 0 forks source link

[vector]学习笔记 #2

Open wutiejun opened 8 years ago

wutiejun commented 8 years ago

vector

http://www.cplusplus.com/reference/vector/

http://www.cplusplus.com/reference/vector/vector/

wutiejun commented 8 years ago

Construct

example:

// constructing vectors
#include <iostream>
#include <vector>

int main ()
{
  // constructors used in the same order as described above:
  std::vector<int> first;                                // empty vector of ints
  std::vector<int> second (4,100);                       // four ints with value 100
  std::vector<int> third (second.begin(),second.end());  // iterating through second
  std::vector<int> fourth (third);                       // a copy of third

  // the iterator constructor can also be used to construct from arrays:
  int myints[] = {16,2,77,29};
  std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );

  std::cout << "The contents of fifth are:";
  for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output:

The contents of fifth are: 16 2 77 29 
wutiejun commented 8 years ago

std::vector::insert

example:

// inserting into a vector
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector (3,100);
  std::vector<int>::iterator it;

  it = myvector.begin();
  it = myvector.insert ( it , 200 );

  myvector.insert (it,2,300);

  // "it" no longer valid, get a new one:
  it = myvector.begin();

  std::vector<int> anothervector (2,400);
  myvector.insert (it+2,anothervector.begin(),anothervector.end());

  int myarray [] = { 501,502,503 };
  myvector.insert (myvector.begin(), myarray, myarray+3);

  std::cout << "myvector contains:";
  for (it=myvector.begin(); it<myvector.end(); it++)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output

myvector contains: 501 502 503 300 300 400 400 200 100 100 100

这个insert有点郁闷,为什么非要绑定一个迭代器呢?按逻辑来说,只要一个索引就行了。 如果非要绑定一个迭代器,则说明vector内部的数据并不是线性的。

另外,参数必需是引用,指针还不行,说明内部是管理的引用:

val
Value to be copied (or moved) to the inserted elements.
Member type value_type is the type of the elements in the container, defined in deque as an alias of its first template parameter (T).

问题:


void CVectorTest::InitData(void)
{
    #define MaxUserCount (100)

    int Index = 0;
    this->Data.clear();
    struct TestData * pData = NULL;
    for (Index = 0; Index < MaxUserCount; Index ++)
    {
        // 直接利用对象集合生成一个新的对象,集合知道对象的空间大小,这里只创建了一个实例
        pData = this->Data.get_allocator().allocate(1);        
        pData->DataID = Index;
        pData->UserID = 10000 + Index;
        sprintf(pData->UserName, "user_%03d", Index);
        this->Data.insert(this->Data.begin(), *pData);
    }
    return;
}

这样的方式添加对象到vector中,感觉会有内存泄漏问题!进一步确认,如果vector是复制了数据到集合中,则必然存在内存泄漏!

wutiejun commented 8 years ago

vector insert问题确认

#include "StdAfx.h"
#include "VectorTest.hpp"
#include "iostream"
#include <windows.h>

using namespace std;

void CVectorTest::InitData(void)
{
    #define MaxUserCount (100)

    int Index = 0;
    this->Data.clear();
    struct TestData * pData = NULL;
    for (Index = 0; Index < MaxUserCount; Index ++)
    {
        // 直接利用对象集合生成一个新的对象,集合知道对象的空间大小,这里只创建了一个实例
        pData = this->Data.get_allocator().allocate(1);
        pData->DataID = Index;
        pData->UserID = 10000 + Index;
        sprintf(pData->UserName, "user_%03d", Index);
        //this->Data.insert(this->Data.begin(), *pData);
        TRACE(_T("%08x\r\n"), pData);
        this->Data.push_back(*pData);
        this->Data.get_allocator().destroy(pData);
    }
    return;
}

void CVectorTest::TraceAllData(void)
{
    std::vector<struct TestData>::iterator it;
    for (it = this->Data.begin() ; it != this->Data.end(); it++)
    {
        cout << it->DataID << ":" << it->UserID << ":" << it->UserName << endl;
    }
}

CVectorTest::CVectorTest(void)
{
    this->InitData();
}

CVectorTest::~CVectorTest(void)
{
    std::vector<struct TestData>::iterator it;
    for (it = this->Data.begin() ; it != this->Data.end(); it++)
    {
        TRACE(_T("%08x\r\n"), it._Ptr);
        this->Data.get_allocator().destroy(it._Ptr);
    }
    this->Data.clear();
}

从代码验证结果证实了向量的管理是复制了一份数据到集合中,同时它的动态增加也更明确的说明它并不是线性管理的,因此性能上会有一些问题,虽然支持"[ ]"操作运算。