【ThinkingInC++】66、pointer Stash的使用

头文件PStash.h

/**
* 书本:【ThinkingInC++】
* 功能:pointer Stash的头文件
* 时间:2014年10月5日14:33:15
* 作者:cutter_point
*/
#ifndef PSTASH_H_INCLUDED
#define PSTASH_H_INCLUDED

class PStash
{
    int quantity;   //内部定义的数据类型的存储块的个数
    int next;       //下一个空的空间的位置
    void** storage;     //指向一个指向void*的指针
    void inflate(int increase); //增加内存空间
public:
    //构造函数
    PStash() : quantity(0), storage(0), next(0) {}
    ~PStash();  //析构函数
    int add(void* element); //添加元素
    void* operator [] (int index) const;    //运算符重载
    void* remove(int index);        //移除index索引下的元素
    int count() const {return next;}    //返回一共有多少个元素
};

#endif // PSTASH_H_INCLUDED

定义文件PStash.cpp

/**
* 书本:【ThinkingInC++】
* 功能:pointer Stash的定义文件
* 时间:2014年10月5日14:33:49
* 作者:cutter_point
*/

#include "PStash.h"
#include "../require.h"
#include <iostream>
#include <cstring>

using namespace std;

/*
    int quantity;   //内部定义的数据类型的存储块的个数
    int next;       //下一个空的空间的位置
    void** storage;     //指向一个指向void*的指针
    void inflate(int increase); //增加内存空间
public:
    //构造函数
    PStash() : quantity(0), storage(0), next(0) {}
    ~PStash();  //析构函数
    int add(void* element); //添加元素
    void* operator [] (int index) const;    //运算符重载
    void* remove(int index);        //移除index索引下的元素
    int count() const {return next;}    //返回一共有多少个元素
*/

void PStash::inflate(int increase)  //增加内存空间
{
    const int psz=sizeof(void*);    //求出每块最小存储单元的长度
    void** st=new void*[quantity+increase]; //增加的空间
    //吧新的空间初始化
    memset(st, 0, (quantity+increase)*psz);
    //吧旧空间的内容拷贝到新空间
    memcpy(st, storage, quantity*psz);
    //吧数据刷新
    quantity+=increase;
    //回收相应的空间
    delete []storage;
    //刷新数据
    storage=st;
}

//    ~PStash();  //析构函数
PStash::~PStash()
{
    for(int i=0 ; i<next ; ++i)
        require(storage[i] == 0, "PStash not cleaned up");
    delete []storage;
}

//int add(void* element); //添加元素
int PStash::add(void* element)
{//添加元素
    //判断给定的空间是否够,不够那就增加
    const int inflateSize=10;   //用来增加长度
    if(next >= quantity)
        inflate(inflateSize);
    //空间够了,那么就吧元素输入到数组里面去
    storage[next++]=element;

    return (next-1);    //吧添加进去的的索引返回
}

//    void* operator [] (int index) const;    //运算符重载
void* PStash::operator [] (int index) const
{
    //要检验给的index是否合理
    require(index >= 0, "PStash::operator [] index negative");
    //既然数据合理,判断数据是否超出了界限
    if(index >= next)
        return 0;
    //返回相应的索引的数据
    return storage[index];
}

//    void* remove(int index);        //移除index索引下的元素
void* PStash::remove(int index)
{
    void* v=operator[](index);
    //移除指针
    if(v != 0)
        storage[index]=0;   //这里吧指针置为0之后,但是没有吧内存的位置改变,下一个加入的内存开始还是next

    return v;
}

最终的测试文件PStashTest.cpp

/**
* 书本:【ThinkingInC++】
* 功能:pointer Stash的测试文件
* 时间:2014年10月5日14:34:23
* 作者:cutter_point
*/

#include "PStash.cpp"
#include "../require.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    PStash intStash;
    for(int i=0 ; i<25 ; ++i)
        intStash.add(new int(i));
    //输出元素内容
    for(int i=0 ; i<intStash.count() ; ++i)
    {
        cout<<"intStash["<<i<<"] = "<<*(int*)intStash[i]<<endl;
    }
    //清除,回收内存
    for(int i=0 ; i<intStash.count() ; ++i)
        delete intStash.remove(i);

    //输出当前文件
    ifstream in("PStashTest.cpp");
    assure(in, "PStashTest.cpp");
    PStash stringStash;
    string line;

    while(getline(in, line))
    {
        stringStash.add(new string(line));
    }

    //输出字符串
    for(int u=0 ; stringStash[u] ; ++u)
        cout<<"stringStash["<<u<<"] ="<<*(string*)stringStash[u]<<endl;

    //清除内存
    for(int v=0 ; v<stringStash.count() ; ++v)
        delete (string*)stringStash.remove(v);

    return 0;
}
时间: 2024-12-07 07:51:55

【ThinkingInC++】66、pointer Stash的使用的相关文章

指针(pointer)的使用

1.变量的指针和指针的变量 变量的指针:变量的存储地址, 指针变量:存储指针的变量 2.指针变量的基本符号 &:取地址符号 *:间接取址符号 NULL||0:初始化 **:多级指针 *p[]:指针数组 3.程序实例(自己 尝试写类函数,一直不懂啥时候才定义变量位为private 1 //*m:定义指针变量 &m:取m的地址 *&m:间接访问 m的内容 2 //&和 *互为逆运算 3 4 #include <iostream> 5 #include<stdl

CSharpGL(36)通用的非托管数组排序方法

如果OpenGL要渲染半透明物体,一个方法是根据顶点到窗口的距离排序,按照从远到近的顺序依次渲染.所以本篇介绍对 UnmanagedArray<T> 进行排序的几种方法. +BIT祝威+悄悄在此留下版了个权的信息说: UnmanagedArray<T> 首先重新介绍一下非托管数组这个东西.一个 UnmanagedArray<float> 与一个 float[] 是一样的用处,只不过 UnmanagedArray<float> 是用 Marshal.Alloc

【ThinkingInC++】49、带内联函数的Stash

Stash4.h /** * 书本:[ThinkingInC++] * 功能:带内联函数的Stash * 时间:2014年9月12日08:16:13 * 作者:cutter_point */ #ifndef STASH4_H_INCLUDED #define STASH4_H_INCLUDED #include "../require.h" #include <iostream> class Stash { int size; //每个空间存储块的字节长度 int quan

C++中单项链表的结点删除问题——为什么我的链表编译能过,但是运行的时候显示:*** Error in `./list&#39;: free(): invalid pointer: 0x08ba20cc *** 已放弃 (核心已转储)

1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 struct student{ 6 int my_id; 7 char name[20]; 8 int my_age; 9 int my_score; 10 student *next = nullptr; 11 student() = default; 12 student(int id,const char *n,int age,int sco

【ThinkingInC++】38、选择重载还是默认参数

头文件 /** * 书本:[ThinkingInC++] * 功能:选择重载还是默认参数,头文件 * 时间:2014年9月6日14:54:28 * 作者:cutter_point */ #ifndef MEM_H_INCLUDED #define MEM_H_INCLUDED typedef unsigned char byte; class Mem { byte* mem; int size; void ensureMinSize(int minSize); //成员函数来增加内存块的大小 p

【ThinkingInC++】31、嵌套友元

/** * 功能:嵌套友元 * 时间:2014年8月21日07:21:29 * 作者:cutter_point */ #include<iostream> #include<cstring> //为了初始化时使用memset() #include<cstdlib> using namespace std; const int sz=20; struct Holder { private: int a[sz]; //一个整形数组 public: void initiali

【ThinkingInC++】25、用sizeof运算符可以确定struct的长度。

/** * 功能:用sizeof运算符可以确定struct的长度. * 时间:2014年8月18日08:10:14 * 作者:cutter_point */ #include"CLib.h" #include"CppLib.h" #include<iostream> using namespace std; struct A { int i[100]; }; struct B { void f(); }; void B::f(){} int main()

Pwn2Own 2014 - AFD.sys Dangling Pointer Vulnerability

这个内核漏洞在Pwn2Own 2014上用来提权绕过IE沙箱(保护模式),siberas公司后来公布了漏洞的细节及利用方法,通过其公开的文档已经能够准确定位漏洞成因及利用方法.(http://www.siberas.de/papers/Pwn2Own_2014_AFD.sys_privilege_escalation.pdf) 第一次分析double free类型的漏洞,并且想通过此漏洞进一步了解学习内核漏洞的利用技术.但分析到占位时,出现了WorkerFactory Object及contro

C++面向对象程序设计 笔记1(Class without pointer members)

一.Class without pointer members (class complex) 1.防卫式声明 #ifndef _COMPLEX_ #define _COMPLEX_ ...... #endif 2.inline function 函数若在class体内完成定义,则自动成为内联函数候选人: 若在class外,需添加inline关键字;同时真正是否inline由编译器决定. class complex{ public: complex (double r = 0, double i