暴走的指压师

为何中年妇女对14岁正太不理不睬?28岁大妈是如何保持14岁身材与脸颊?三无蓝毛究竟身在何处?为何少年抛弃妹子去寻找基友的菊花,大妈抛弃正太去和眼镜妹百合? 一切的一切,请看《Q ヱヴァンゲリヲン新劇場版:Q 》
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

c语言 面向对象的栈

Posted on 2010-12-02 17:24  晓彻  阅读(402)  评论(0编辑  收藏  举报

今天闲来无事,实现了一个c语言的面向对象栈。额,思路仿照 C++ stl里面的vector,当容量不够自动扩充2倍的容量。但是经过测试,这个会出错。现在死也不明白为什么reallocate返回为null,用malloc也一样(我试过)。希望有感兴趣的网友能够找出错误。小弟先行谢过。~

 

(2010.12.3更新。找到问题了。最新的代码在google code上可以下载。原0.8版本的问题描述如下)

google code源码下载链接:http://code.google.com/p/simple-c-library/downloads/

恩,先把代码贴出来:

 

//问题有三处
        val = __newstack__->top;
        __newstack__->top -= sizeof(T);
//这是第一处,应该改为:
__newstack__->top --;

//第二处:
  __newstack__->top = __newstack__->base+sizeof(T)*__newstack__->elements;
//改为:
__newstack__->top = __newstack__->base+__newstack__->elements;

//第三处: memcpy(__newstack__->top,val,sizeof(T));   __newstack__->top += sizeof(T); //改为:
__newstack__->top ++;

 

当然,这是我的代码中指针偏移错误。由于base,top已经声明为T*类型,所以在内存中只需要指针++便可以一次性移动32b长度,但是我原来的代码中都是加上sizeof(T),这一句错误的偏移导致程序的堆空间异常从而无法申请到空间的诡异现象。

 

现在贴上release-1.0的代码:

 

/*
 * xiaoyang yi @2010.12.2
 *
 * A simple C object Stack.
 * Wanning:Before you new a stack,stack_capacity should be assigned.
 */
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define __ERROR__(str)	printf("%s",str)
typedef int T;
/*
___________
|____5____| <---- 5-top(no value)
|____4____|    |
|____3____|    |
|____2____|    |
|____1____| <---- 1-base(first value)

*/
typedef struct _obj_stack{
    T* base;/*warning:it won't release space pointing to *item*/
    T* top;
    int capacity;/*capacity of stack*/
    int elements;/*count of elements*/

	/*stack interface*/
	//struct _obj_stack* (*new_stack)();
	int (*push)( T* val);
	int (*pop)();
	void (*release)();
	T* (*stack_get)(int pos);
}obj_stack;

//--------------------------------------------------------------------------------
/*stack function*/
int _obj_push(T* val);
void _obj_release();
int _obj_pop();
obj_stack* new_obj_stack();
T* _obj_stack_get(int pos);
//--------------------------------------------------------------------------------
int stack_capacity;
T* _temp_;
obj_stack* __newstack__;
//--------------------------------------------------------------------------------

obj_stack* new_obj_stack()
{
    if(stack_capacity <= 0){
        return NULL;
    }

    __newstack__ = (obj_stack*)malloc(sizeof(obj_stack));
    if(__newstack__ == NULL){
		__ERROR__("error:malloc failed!\n");
        return NULL;
    }

    __newstack__->capacity = stack_capacity;
    __newstack__->elements = 0;
	__newstack__->base = (T*)malloc(sizeof(T)*(__newstack__->capacity));
	__newstack__->top = __newstack__->base;

	__newstack__->pop = _obj_pop;
	__newstack__->push = _obj_push;
	__newstack__->release = _obj_release;
	__newstack__->stack_get = _obj_stack_get;

    return __newstack__;
}

/*pop without return value*/
int _obj_pop()
{
    T *val = NULL;
    if(__newstack__->elements <= 0){
		__ERROR__("warnning:stack is empty!\n");
        return -1;
    }else{
        val = __newstack__->top;
        __newstack__->top -= sizeof(T);
        __newstack__->elements--;
    }

    return 1;
}

int _obj_push( T* val)
{
    if(val == NULL | __newstack__ == NULL){
		__ERROR__("error:null params!\n");
        return -1;
    }

	/*if space is enough,malloc again*/
    if(__newstack__->elements >= __newstack__->capacity){
		_temp_ = __newstack__->base;
		//m_stack->base = (T*)malloc(sizeof(T)*(m_stack->capacity)*2);
		//m_stack->base = (T*)malloc(80);
		__newstack__->base = realloc(__newstack__->base,__newstack__->capacity*2*sizeof(T));
		
		if (__newstack__->base == NULL){
			__newstack__->base = _temp_;
			__ERROR__("error:malloc failed!\n");
			return -1;
		}

		memcpy(__newstack__->base,_temp_,sizeof(T)*__newstack__->capacity);
		__newstack__->capacity <<= 1 ;

		__newstack__->elements = __newstack__->elements;
		__newstack__->top = __newstack__->base+__newstack__->elements;
		//free(_temp_);
    }

	memcpy(__newstack__->top,val,sizeof(T));
    __newstack__->top ++;
	__newstack__->elements++;

    return 1;
}

/*random access to stack*/
T* _obj_stack_get( int pos)
{
	if (pos < 0 | __newstack__->elements < pos){
		__ERROR__("warnning:out of boudry!\n");
		return NULL;
	}

	return (__newstack__->base+ pos);
}

/*
 * warning:it just frees the space of struct and content in stack together!
 * if you don't want delete the content,just free(m_stack)
 */
void _obj_release()
{
	free(__newstack__->base);
	free(__newstack__);
}

//--------------------------------------------------------------------------------
/*test stack*/
#define MAX	200
int main()
{
	obj_stack *newstack1 = NULL;
	int i = 0;
	T *val = NULL;
	T a[MAX] = {1,2,3,4,5,6,7,8,9,0};

	for( i = 0; i < MAX; i++){
		a[i] = i;
	}

	stack_capacity = 5;
	newstack1 = new_obj_stack();

	for (i = 0;i < MAX; i++){
		newstack1->push(&a[i]);
	}
	
	newstack1->pop();
	for (i = 0;i < MAX; i++){
		/*before using val you need to check it*/
		val = newstack1->stack_get(i);
		if (val != NULL){
			printf("%d\t",(T)(*val));
		}

	}
	newstack1->release();
	getchar();
	return 0;
}