贴代码:
stack.h
struct stack
{
void * elems; //指向栈中首元素
int logicallen; //当前栈空间中的元素个数
int allocalength;//栈空间的实际大小
int elemSize;//栈中元素占用字节数
void (*freefn)(void *); //函数指针,清除函数指针
};
stack.cpp
#include "stack.h"
#include <iostream.h>
#include<stdlib.h>
#include "assert.h"
#include "memory.h"
#include "string.h"
#include <stdio.h>
void objdelete(void * elem){
if(elem == NULL){
return;
}
//char ** elem 获得elem指针的地址,然后* X表示获得上面地址存放的指针
//char ** 相当强制转换elem为指针的指针,指向的是一个指针,前面加*号就是获得elem指针。
//转化为二级指针,距离真正的字符有两跳之遥,然后解引用
free(*(char**)elem);
}
/************************************************************************/
/* 创建一个栈空间 */
/************************************************************************/
void stackNew(stack *s,int elemSize,void (*freefn)(void *)){
s->logicallen=0;
s->allocalength=4;
s->elemSize=elemSize;
s->elems=malloc(4*elemSize); //申请栈空间
s->freefn = freefn;
};
/************************************************************************/
/* 释放栈空间 */
/************************************************************************/
void stackDispose(stack *s){
if(s->freefn != NULL){
for(int i=0;i<s->logicallen;i++){
void * target = (char*)s->elems+i*s->elemSize;
s->freefn(target);
}
}
free(s->elems);
};
void StackPop(stack *s,void *elemAddr)
{
void *sourse=(char *)s->elems+(s->logicallen-1)*s->elemSize;
memcpy(elemAddr,sourse,s->elemSize);
s->logicallen--;
}
/************************************************************************/
/* chuzhan */
/************************************************************************/
/************************************************************************/
/* 将元素elem入栈 */
/************************************************************************/
//
// void stackPush(stack *s,void *add){
//
// if(s->logicallen == s->allocalength){
// s->allocalength *=2; //等价于s->allocalength = s->allocalength*2
// s->elems = (int *)realloc(s->elems,s->allocalength*sizeof(int));
// }
// assert(s->elems != NULL);
// s->elems[s->logicallen] =value;
// s->logicallen++;
// };
void stackGrow(stack *s){
s->allocalength*=2;
s->elems = realloc(s->elems,s->elemSize*s->allocalength);
}
/************************************************************************/
/* 将元素elem入栈 */
/************************************************************************/
void stackPush(stack *s,void *elemAddr){
if(s->logicallen == s->allocalength){
stackGrow(s); //需要扩容了
}
//手动计算元素地址,因为void*类型,系统比不知道该怎么处理。所以需要自己计算出入栈和出栈时元素的地址。
//从add地址下的内容拷贝到target的地址,拷贝长度为elemSize
cout<<"elems"<<s->elems<<endl;
cout<<"logicallen"<<s->logicallen<<endl;
cout<<"elemSize"<<s->elemSize<<endl;
void * target = (char *)s->elems+s->logicallen*s->elemSize;
memcpy(target,elemAddr,s->elemSize);
s->logicallen++;
};
void main(){
const char *friends[3] = {"Al","Bob","Carl"};
stack *s=new stack();
stackNew(s,sizeof(char *),objdelete);
int leng = sizeof(friends)/4;
cout<<leng<<endl;
for(int i=0;i<leng;i++){
char * copy=strdup(friends[i]);//strdup内部调用了malloc,需释放内存;返回指向被复制的字符串的指针
stackPush(s,©);
}
char *name;
// for(int idx=0;idx<3;idx++)
// {
// StackPop(s,&name);
// }
stackDispose(s);
}
总结:
下面这个方法就是获得top的地址。入栈。
void * target = (char *)s->elems+s->logicallen*s->elemSize;