16从汇编的角度深入理解c++_深入理解Vector(自己编写代码实现Vector中的函数)
c语言中有三座大山:指针、递归、数据结构。
数据结构有3种必须掌握:Vector、链表、二叉树,不然以后逆向别人的游戏,都看不懂是什么。
因此需要:
1、首先自己编写代码实现Vector、链表、二叉树,自己才能知道3种数据结构本质是什么。
2、分析反汇编,Vector、链表、二叉树在反汇编中长什么样,这样逆向的时候,你以后才可以认识。
这里先学习第一种:Vector
先自己手动写第一遍的代码,如下:
#include <stdio.h>
/*
vector::clear( )
vector::capacity( )
vector::pop_back( )
vector::push_back( )
vector::at( )
vector::empty( )
vector::insert( )
vector::erase( )
vector::size( )
*/
template<class E_ELEMENT>
class Vector
{
public:
MyVector(); //初始化,分配空间
MyVector(dword size); //按照参数分配空间
~MyVector(); //回收资源
public:
void clear(); //清空容器
DWORD capacity(); //返回容器容量
void pop_back(); //删除最后1个元素
bool push_back(E_ELEMENT element); //1个元素放到末尾
void at(DWORD index,E_ELEMENT* lpElement); //获得元素的内容
bool empty(); //判断容器是否为空
bool insert(DWORD index,E_ELEMENT Element); //在指定位置插入1个元素
void erase(DWORD index); //删除指定元素
DWORD size(); //返回当前容器中元素个数
void expand(); //扩容函数
private:
DWORD m_Initsize; //初始化大小
DWORD m_increment; //每次新增空间大小
DWORD m_index; //当前容器可以存储元素的索引位置
DWORD m_length; //容器大小
E_ELEMENT* m_lpVector; //容器指针
};
//不带参数的初始化,初始化为10个变量的大小,每次新增空间为5
MyVector<E_ELEMENT>::MyVector():m_Initsize(10),m_increment(5){
//初始化分配空间,这里不应该重新定义,应该是直接使用成员变量
E_ELEMENT* m_lpVector = new E_ELEMENT[10];
//从0开始存储元素
m_index = 0;
m_length = m_Initsize;
};
MyVector<E_ELEMENT>::MyVector(DWORD size):m_increment(5){
//这里不应该重新定义,应该是直接使用成员变量
E_ELEMENT* m_lpVector = new E_ELEMENT[size];
m_index = 0;
m_length = size;
m_Initsize = size;
};
MyVector<E_ELEMENT>::~MyVector(){
delete[] m_lpVector;
m_lpVector = NULL;
};
void MyVector<E_ELEMENT>::expand(){
E_ELEMENT* temp = new E_ELEMENT[m_length+m_increment];
memcpy(temp,m_lpVector,sizeof(E_ELEMENT)*m_length);
m_lpVector = temp;
temp = NULL;
m_length = m_length + m_increment;
};
bool MyVector<E_ELEMENT>::push_back(E_ELEMENT element){
//判断容器是否满
if(m_index > m_length)
{
expand();//扩容
}
E_ELEMENT* temp = new E_ELEMENT[m_length+m_increment];
memcpy(temp,m_lpVector,sizeof(E_ELEMENT)*m_length);
m_lpVector = temp;
temp = NULL;
memcpy(m_lpVector+m_index,&element,sizeof(E_ELEMENT));
m_index++;
m_length = m_length + m_increment;
return true;
};
bool MyVector<E_ELEMENET>::insert(DWORD index,E_ELEMENT Element){
//索引错误的情况
if(index < 0 || index > m_index)
{
return INDEX_ERROR;
}
//插入最后的情况
if(index == m_index ){
expand();
}
//移动位置
for(int j = m_index;m_index > index;m_index--)
{
memcpy(m_lpVector + m_index,m_lpVector + m_index - 1,sizeof(E_ELEMENT));
}
//插入
memcpy(m_lpVector + index,&element,sizeof(E_ELEMENT));
//修改属性Vector相关属性值
m_index++;
m_length++;
};
void MyVector<E_ELEMENET>::at(DWORD index,E_ELEMENT* lpElement){
if(index < 0 || index > m_index)
{
return INDEX_ERROR;
}
memcpy(lpElement,m_lpVector+index,sizeof(E_ELEMENET));
};
void MyVector<E_ELEMENET>::pop_back(){
m_index--;
memset(m_lpVector+m_index,0,sizeof(E_ELEMENET));
};
DWORD MyVector<E_ELEMENET>::capacity(){
return m_length;
};
void MyVector<E_ELEMENET>::clear(){
memset(m_lpVector,0,sizeof(E_ELEMENET)*m_length);
m_index = 0;
};
bool MyVector<E_ELEMENET>::empty(){
if(m_index == 0)
{
return true;
}else{
return false;
}
};
void MyVector<E_ELEMENET>::erase(DWORD index){
if(index < 0 || index >= m_index)
{
return INDEX_ERROR;
}
for(int j = index;j < m_index-1;j++)
{
memcpy(m_lpVector+index,m_lpVector+index+1,sizeof(E_ELEMENET));
}
m_index--;
memset(m_lpVector + m_index,0,sizeof(E_ELEMENET));
};
DWORD MyVector<E_ELEMENET>::size(){
return m_index-1;
};
int main(int argc, char *argv[])
{
printf("Hello, world\n");
return 0;
}
以上代码存在调试的时候发现有很多问题,进行第一次修改:
#define DWORD int
#define INDEX_ERROR -1
/*
vector::clear( )
vector::capacity( )
vector::pop_back( )
vector::push_back( )
vector::at( )
vector::empty( )
vector::insert( )
vector::erase( )
vector::size( )
*/
class Person{
public:
int age;
char* name;
bool sex;
public:
Person(){
age = 18;
name = "小明";
sex = 1;
}
Person(int age,char* name,bool sex){
this->age = age;
this->name = name;
this->sex = sex;
}
~Person(){
}
};
template<class E_ELEMENT>
class MyVector
{
public:
MyVector(); //初始化,分配空间
MyVector(DWORD size); //按照参数分配空间
~MyVector(); //回收资源
public:
void clear(); //清空容器
DWORD capacity(); //返回容器容量
void pop_back(); //删除最后1个元素
bool push_back(E_ELEMENT element); //1个元素放到末尾
void at(DWORD index,E_ELEMENT* lpElement); //获得元素的内容
bool empty(); //判断容器是否为空
bool insert(DWORD index,E_ELEMENT Element); //在指定位置插入1个元素
void erase(DWORD index); //删除指定元素
DWORD size(); //返回当前容器中元素个数
void expand(); //扩容函数
private:
DWORD m_Initsize; //初始化大小
DWORD m_increment; //每次新增空间大小
DWORD m_index; //当前容器可以存储元素的索引位置
DWORD m_length; //容器大小
E_ELEMENT* m_lpVector; //容器指针
};
//不带参数的初始化,初始化为10个变量的大小,每次新增空间为5
template<class E_ELEMENT>
MyVector<E_ELEMENT>::MyVector():m_Initsize(4),m_increment(5){
//初始化分配空间
m_lpVector = new E_ELEMENT[m_Initsize];
memset(m_lpVector,0,sizeof(E_ELEMENT)*m_Initsize);
//从0开始存储元素
m_index = 0;
m_length = m_Initsize;
};
template<class E_ELEMENT>
MyVector<E_ELEMENT>::MyVector(DWORD size):m_increment(5){
m_lpVector = new E_ELEMENT[size];
memset(m_lpVector,0,sizeof(E_ELEMENT)*size);
m_index = 0;
m_length = size;
m_Initsize = size;
};
template<class E_ELEMENT>
MyVector<E_ELEMENT>::~MyVector(){
delete[] m_lpVector;
m_lpVector = NULL;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::expand(){
E_ELEMENT* temp = new E_ELEMENT[m_length+m_increment];
memcpy(temp,m_lpVector,sizeof(E_ELEMENT)*m_length);
m_lpVector = temp;
temp = NULL;
m_length = m_length + m_increment;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::push_back(E_ELEMENT element){
//判断容器是否满
if(m_index > m_length)
{
expand();//扩容
}
E_ELEMENT* temp = new E_ELEMENT[m_length+m_increment];
memcpy(temp,m_lpVector,sizeof(E_ELEMENT)*m_length);
m_lpVector = temp;
temp = NULL;
memcpy(m_lpVector+m_index,&element,sizeof(E_ELEMENT));
m_index++;
m_length = m_length + m_increment;
return true;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::insert(DWORD index,E_ELEMENT Element){
//索引错误的情况
if(index < 0 || index > m_index)
{
return INDEX_ERROR;
}
//插入最后的情况
if(index == m_index ){
expand();
}
//移动位置
for(int j = m_index;m_index > index;m_index--)
{
memcpy(m_lpVector + m_index,m_lpVector + m_index - 1,sizeof(E_ELEMENT));
}
//插入
memcpy(m_lpVector + index,&element,sizeof(E_ELEMENT));
//修改属性Vector相关属性值
m_index++;
m_length++;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::at(DWORD index,E_ELEMENT* lpElement){
if(index < 0 || index > m_index)
{
return INDEX_ERROR;
}
memcpy(lpElement,m_lpVector+index,sizeof(E_ELEMENET));
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::pop_back(){
m_index--;
memset(m_lpVector+m_index,0,sizeof(E_ELEMENET));
};
template<class E_ELEMENT>
DWORD MyVector<E_ELEMENT>::capacity(){
return m_length;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::clear(){
memset(m_lpVector,0,sizeof(E_ELEMENT)*m_length);
m_index = 0;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::empty(){
if(m_index == 0)
{
return true;
}else{
return false;
}
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::erase(DWORD index){
if(index < 0 || index >= m_index)
{
return INDEX_ERROR;
}
for(int j = index;j < m_index-1;j++)
{
memcpy(m_lpVector+index,m_lpVector+index+1,sizeof(E_ELEMENET));
}
m_index--;
memset(m_lpVector + m_index,0,sizeof(E_ELEMENET));
};
template<class E_ELEMENET>
DWORD MyVector<E_ELEMENET>::size(){
return m_index-1;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyVector<Person>* lpMyV1 = new MyVector<Person>();
MyVector<int>* lpMyV2 = new MyVector<int>(3);
printf("%d,%d\n",lpMyV1->capacity(),sizeof(lpMyV1));
printf("%d,%d\n",lpMyV2->capacity(),sizeof(lpMyV2));
getchar();
return 0;
}
第二次修改代码,主要是插入元素、添加到最后1个元素的时候,判断条件有点问题:
#define DWORD int
#define INDEX_ERROR -1
/*
vector::clear( )
vector::capacity( )
vector::pop_back( )
vector::push_back( )
vector::at( )
vector::empty( )
vector::insert( )
vector::erase( )
vector::size( )
*/
class Person{
public:
int age;
char* name;
bool sex;
public:
Person(){
age = 18;
name = "小明";
sex = 1;
}
Person(int age,char* name,bool sex){
this->age = age;
this->name = name;
this->sex = sex;
}
~Person(){
}
};
template<class E_ELEMENT>
class MyVector
{
public:
MyVector(); //初始化,分配空间
MyVector(DWORD size); //按照参数分配空间
~MyVector(); //回收资源
public:
void clear(); //清空容器
DWORD capacity(); //返回容器容量
void pop_back(); //删除最后1个元素
bool push_back(E_ELEMENT element); //1个元素放到末尾
void at(DWORD index,E_ELEMENT* lpElement); //获得元素的内容
bool empty(); //判断容器是否为空
bool insert(DWORD index,E_ELEMENT Element); //在指定位置插入1个元素
void erase(DWORD index); //删除指定元素
DWORD size(); //返回当前容器中元素个数
void expand(); //扩容函数
private:
DWORD m_Initsize; //初始化大小
DWORD m_increment; //每次新增空间大小
DWORD m_index; //当前容器可以存储元素的索引位置
DWORD m_length; //容器大小
E_ELEMENT* m_lpVector; //容器指针
};
//不带参数的初始化,初始化为10个变量的大小,每次新增空间为5
template<class E_ELEMENT>
MyVector<E_ELEMENT>::MyVector():m_Initsize(4),m_increment(5){
//初始化分配空间
m_lpVector = new E_ELEMENT[m_Initsize];
memset(m_lpVector,0,sizeof(E_ELEMENT)*m_Initsize);
//从0开始存储元素
m_index = 0;
m_length = m_Initsize;
};
template<class E_ELEMENT>
MyVector<E_ELEMENT>::MyVector(DWORD size):m_increment(5){
m_lpVector = new E_ELEMENT[size];
memset(m_lpVector,0,sizeof(E_ELEMENT)*size);
m_index = 0;
m_length = size;
m_Initsize = size;
};
template<class E_ELEMENT>
MyVector<E_ELEMENT>::~MyVector(){
delete[] m_lpVector;
m_lpVector = NULL;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::expand(){
E_ELEMENT* temp = new E_ELEMENT[m_length+m_increment];
memcpy(temp,m_lpVector,sizeof(E_ELEMENT)*m_length);
delete[] m_lpVector;
m_lpVector = temp;
temp = NULL;
m_length = m_length + m_increment;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::push_back(E_ELEMENT element){
//判断容器是否需要增容,等于的时候也要增容,因为添加完这个元素就要增容了。
if(m_index >= m_length)
{
expand();//扩容
}
memcpy(m_lpVector+m_index,&element,sizeof(E_ELEMENT));
m_index++;
return true;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::insert(DWORD index,E_ELEMENT Element){
//索引错误的情况
if(index < 0 || index > m_index)
{
return INDEX_ERROR;
}
//是否需要增容
if(m_index >= m_length ){
expand();
}
//移动位置
for(int j = m_index;m_index > index;j--)
{
memcpy(m_lpVector + m_index,m_lpVector + m_index - 1,sizeof(E_ELEMENT));
}
//插入
memcpy(m_lpVector + index,&element,sizeof(E_ELEMENT));
//修改属性Vector相关属性值
m_index++;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::at(DWORD index,E_ELEMENT* lpElement){
if(index < 0 || index >= m_index)
{
return INDEX_ERROR;
}
memcpy(lpElement,m_lpVector+index,sizeof(E_ELEMENET));
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::pop_back(){
m_index--;
memset(m_lpVector+m_index,0,sizeof(E_ELEMENET));
};
template<class E_ELEMENT>
DWORD MyVector<E_ELEMENT>::capacity(){
return m_length;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::clear(){
memset(m_lpVector,0,sizeof(E_ELEMENT)*m_length);
m_index = 0;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::empty(){
if(m_index == 0)
{
return true;
}else{
return false;
}
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::erase(DWORD index){
if(index < 0 || index >= m_index)
{
return INDEX_ERROR;
}
for(int j = index;j < m_index-1;j++)
{
memcpy(m_lpVector+index,m_lpVector+index+1,sizeof(E_ELEMENET));
}
m_index--;
memset(m_lpVector + m_index,0,sizeof(E_ELEMENET));
};
template<class E_ELEMENET>
DWORD MyVector<E_ELEMENET>::size(){
return m_index-1;
};
查看反汇编,执行流程:

当为Person的时候 ,执行流程:
1、当m_lpVector = new E_ELEMENT[m_Initsize]的时候,会先初始化m_Initsize=4,m_increment=5,然后使用malloc(new的本质)分配空间
2、然后循环调用Person的默认无参的构造函数初始化。
3、调用memset来全部初始化为0。
4、0x00717050的位置存储的就是Vector对象,而Vector中最后1个元素0x007170a4这个值,指向容器存储的内容。
当为int的时候,内存情况:

注意:
使用模板类初始化的时候,如果使用的不是int、short、char基本类型,使用的是类,那么初始化的方式:
MyVector<Person>* lpMyV1 = new MyVector<Person>(); (*lpMyV1).push_back(Person(18,"小马",1)); (*lpMyV1).push_back(Person(20,"小明",0)); (*lpMyV1).push_back(Person(19,"小李",1)); (*lpMyV1).push_back(Person(20,"小红",22));
第三次修改代码,使用Vector分别对对象和int类型等进行试验,然后查看对应的反汇编代码:
//MyVector.h头文件
#define DWORD int
#define INDEX_ERROR 0
#define BOOL bool
/*
vector::clear( )
vector::capacity( )
vector::pop_back( )
vector::push_back( )
vector::at( )
vector::empty( )
vector::insert( )
vector::erase( )
vector::size( )
*/
class Person{
public:
int age;
char* name;
bool sex;
public:
Person(){
age = 18;
name = "小明";
sex = 1;
}
Person(int age,char* name,bool sex){
this->age = age;
this->name = name;
this->sex = sex;
}
~Person(){
}
};
template<class E_ELEMENT>
class MyVector
{
public:
MyVector(); //初始化,分配空间
MyVector(DWORD size); //按照参数分配空间
~MyVector(); //回收资源
public:
void clear(); //清空容器
DWORD capacity(); //返回容器容量
void pop_back(); //删除最后1个元素
bool push_back(E_ELEMENT element); //1个元素放到末尾
int at(DWORD index,E_ELEMENT* lpElement); //获得元素的内容
bool empty(); //判断容器是否为空
bool insert(DWORD index,E_ELEMENT Element); //在指定位置插入1个元素
BOOL erase(DWORD index); //删除指定元素
DWORD size(); //返回当前容器中元素个数
void expand(); //扩容函数
private:
DWORD m_Initsize; //初始化大小
DWORD m_increment; //每次新增空间大小
DWORD m_index; //当前容器可以存储元素的索引位置
DWORD m_length; //容器大小
E_ELEMENT* m_lpVector; //容器指针
};
//不带参数的初始化,初始化为10个变量的大小,每次新增空间为5
template<class E_ELEMENT>
MyVector<E_ELEMENT>::MyVector():m_Initsize(4),m_increment(5){
//初始化分配空间
m_lpVector = new E_ELEMENT[m_Initsize];
memset(m_lpVector,0,sizeof(E_ELEMENT)*m_Initsize);
//从0开始存储元素
m_index = 0;
m_length = m_Initsize;
};
template<class E_ELEMENT>
MyVector<E_ELEMENT>::MyVector(DWORD size):m_increment(5){
m_lpVector = new E_ELEMENT[size];
memset(m_lpVector,0,sizeof(E_ELEMENT)*size);
m_index = 0;
m_length = size;
m_Initsize = size;
};
template<class E_ELEMENT>
MyVector<E_ELEMENT>::~MyVector(){
delete[] m_lpVector;
m_lpVector = NULL;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::expand(){
E_ELEMENT* temp = new E_ELEMENT[m_length+m_increment];
memset(temp,0,sizeof(E_ELEMENT)*(m_length+m_increment));
memcpy(temp,m_lpVector,sizeof(E_ELEMENT)*m_length);
delete[] m_lpVector;
m_lpVector = temp;
temp = NULL;
m_length = m_length + m_increment;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::push_back(E_ELEMENT element){
//判断容器是否需要增容,等于的时候也要增容,因为添加完这个元素就要增容了。
if(m_index >= m_length)
{
expand();//扩容
}
memcpy(m_lpVector+m_index,&element,sizeof(E_ELEMENT));
m_index++;
return true;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::insert(DWORD index,E_ELEMENT Element){
//索引错误的情况
if(index < 0 || index > m_index)
{
return INDEX_ERROR;
}
//是否需要增容
if(m_index >= m_length ){
expand();
}
//移动位置
for(int j = m_index;j > index;j--)
{
memcpy(m_lpVector + j,m_lpVector + j - 1,sizeof(E_ELEMENT));
}
//插入
memcpy(m_lpVector + index,&Element,sizeof(E_ELEMENT));
//修改属性Vector相关属性值
m_index++;
return true;
};
template<class E_ELEMENT>
int MyVector<E_ELEMENT>::at(DWORD index,E_ELEMENT* lpElement){
if(index < 0 || index >= m_index)
{
return INDEX_ERROR;
}
memcpy(lpElement,m_lpVector+index,sizeof(E_ELEMENT));
return true;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::pop_back(){
m_index--;
memset(m_lpVector+m_index,0,sizeof(E_ELEMENT));
};
template<class E_ELEMENT>
DWORD MyVector<E_ELEMENT>::capacity(){
return m_length;
};
template<class E_ELEMENT>
void MyVector<E_ELEMENT>::clear(){
memset(m_lpVector,0,sizeof(E_ELEMENT)*m_length);
m_index = 0;
};
template<class E_ELEMENT>
bool MyVector<E_ELEMENT>::empty(){
if(m_index == 0)
{
return true;
}else{
return false;
}
};
template<class E_ELEMENT>
BOOL MyVector<E_ELEMENT>::erase(DWORD index){
if(index < 0 || index >= m_index)
{
return INDEX_ERROR;
}
for(int j = index;j < m_index-1;j++)
{
memcpy(m_lpVector+index,m_lpVector+index+1,sizeof(E_ELEMENT));
}
m_index--;
memset(m_lpVector + m_index,0,sizeof(E_ELEMENT));
return true;
};
template<class E_ELEMENT>
DWORD MyVector<E_ELEMENT>::size(){
return m_index-1;
};
源代码文件:
// 15C++MyVectorTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "MyVector.h"
#include <string.h>
/*
vector::clear( ) //清空容器
vector::capacity( ) //容量
vector::pop_back( )
vector::push_back( )
vector::at( )
vector::empty( ) //是否为空
vector::insert( )
vector::erase( ) //删除指定元素
vector::size( ) //元素个数
*/
int _tmain(int argc, _TCHAR* argv[])
{
MyVector<int>* lpMyV1 = new MyVector<int>;
MyVector<Person>* lpMyV2 = new MyVector<Person>(3);
lpMyV1->push_back(1);
lpMyV1->push_back(2);
lpMyV1->push_back(3);
lpMyV1->push_back(4);
lpMyV1->push_back(5);
lpMyV1->push_back(6);
int x=0;
lpMyV1->insert(3,9);
lpMyV1->at(3,&x);
printf("输出第3个元素:%d\n",x);
lpMyV1->pop_back();
printf("当前容器的容量:%d\n",lpMyV1->capacity());
lpMyV1->erase(4);
printf("当前容器中元素个数:%d\n",lpMyV1->size());
printf("容器是否为空:%d\n",lpMyV1->empty());
lpMyV1->clear();
printf("清空之后,判断是否为空:%d\n",lpMyV1->empty());
lpMyV2->push_back(Person(1,"小马",1));
lpMyV2->push_back(Person(2,"小明",0));
lpMyV2->push_back(Person(3,"小李",1));
lpMyV2->push_back(Person(4,"小红",1));
lpMyV2->insert(3,Person(5,"小黑",0));
printf("扩容一次后,当前容器的容量:%d\n",lpMyV2->capacity());
lpMyV2->pop_back();
lpMyV2->erase(2);
printf("当前容器中元素个数:%d\n",lpMyV2->size());
printf("删除1个元素只好,当前容器的容量:%d\n",lpMyV2->capacity());
printf("容器是否为空:%d\n",lpMyV2->empty());
lpMyV2->clear();
printf("清空之后,判断是否为空:%d\n",lpMyV2->empty());
getchar();
return 0;
}

浙公网安备 33010602011771号