晓彻

Links

C Object Stack Implementation

Sat, 04 Dec 2010 07:04:03 +0800 | Comments(174) | Category:linux-embedded | Tags:

I implemented a objective stack container Last Week,used for a simple compiler.It made me  crazy when happened to some strange exception of pointer...Now,it has been released.

code as following:

 

/*
 * 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;
}

 

If there are some other errors,you can post email to me: hityixiaoyang@gmail.com.