自己写个malloc函数,从ucos 2移植过来

由于写arm裸机程序,需要用到malloc,进行动态内存管理,所以就试着自己搞个简单的内存管理。

若其中有纰漏,还忘指正。


此动态内存管理源自ucos的动态内存管理,比较简陋,同样的动态内存管理还有Doug Lea  的dlmalloc,不多说切入正题。

由于ucos动态内存管理很多人已经讲过,所以现贴下代码。

malloc.h

/*
*********************************************************************************************************
*                                              uC/OS-II
*                                        The Real-Time Kernel
*
*                            (c) Copyright 1992-2012, Micrium, Weston, FL
*                                           All Rights Reserved
*
* File    : uCOS_II.H
* By      : Jean J. Labrosse
* Version : V2.92.07
*
* LICENSING TERMS:
* ---------------
*   uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using  uC/OS-II  in a commercial product you need to contact Micrium to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II.   The fact that the  source is provided does  NOT  mean that you can use it without  paying a
* licensing fee.
*********************************************************************************************************
*/

#ifndef   OS_uCOS_II_H
#define   OS_uCOS_II_H


#ifndef   debug
#define   debug
#endif


#undef  debug//卸载  debug
#define    OS_EXT   extern
                                       /* --------------------- MEMORY MANAGEMENT -------------------- */
#define OS_MEM_EN                 1    /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_NAME_EN            1    /*     Enable memory partition names                            */
#define OS_MEM_QUERY_EN           1    /*     Include code for OSMemQuery()                            */


#define OS_MAX_MEM_PART           5    /* Max. number of memory partitions                             */
/*
*********************************************************************************************************
*                                       uC/OS-II VERSION NUMBER
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*                                              DATA TYPES
*                                         (Compiler Specific)
*********************************************************************************************************
*/
typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned short INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   short INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned int   INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   int   INT32S;                   /* Signed   32 bit quantity                           */
typedef float          FP32;                     /* Single precision floating point                    */
typedef double         FP64;                     /* Double precision floating point                    */
typedef unsigned int   OS_STK;                   /* Each stack entry is 32-bit wide                    */
typedef unsigned int   OS_CPU_SR;                /* Define size of CPU status register (PSR = 32 bits) */

/*
*********************************************************************************************************

*                                  MEMORY PARTITION DATA STRUCTURES
*********************************************************************************************************
*/

typedef struct os_mem {                   /* MEMORY CONTROL BLOCK                                      */
    void   *OSMemAddr;                    /* Pointer to beginning of memory partition                  */
    void   *OSMemFreeList;                /* Pointer to list of free memory blocks                     */
    INT32U  OSMemBlkSize;                 /* Size (in bytes) of each block of memory                   */
    INT32U  OSMemNBlks;                   /* Total number of blocks in this partition                  */
    INT32U  OSMemNFree;                   /* Number of memory blocks remaining in this partition       */
#if OS_MEM_NAME_EN > 0u
    INT8U  *OSMemName;                    /* Memory partition name                                     */
#endif
}OS_MEM;

typedef struct os_mem_data {
    void   *OSAddr;                    /* Pointer to the beginning address of the memory partition     */
    void   *OSFreeList;                /* Pointer to the beginning of the free list of memory blocks   */
    INT32U  OSBlkSize;                 /* Size (in bytes) of each memory block                         */
    INT32U  OSNBlks;                   /* Total number of blocks in the partition                      */
    INT32U  OSNFree;                   /* Number of memory blocks free                                 */
    INT32U  OSNUsed;                   /* Number of memory blocks used                                 */
} OS_MEM_DATA;
/*
    os_strlen function
*/

#define  OS_ARG_CHK_EN             0    /* Enable (1) or Disable (0) argument checking                  */
#define  OS_ASCII_NUL            (INT8U)0




#define  OS_VERSION                 29207u              /* Version of uC/OS-II (Vx.yy mult. by 10000)  */


#define OS_ARG_CHK_EN             0    /* Enable (1) or Disable (0) argument checking                  */


#define  OS_CRITICAL_METHOD           3u

#if OS_CRITICAL_METHOD == 3u
#define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}
#define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}
#endif



#define  blockSize    16
#define  nblock       (20*1024)
void  OS_MemInit (void);
void *malloc(INT8U size);
void meminit(void);
void  free(void *memb);
/*
*********************************************************************************************************
*                                             ERROR CODES
*********************************************************************************************************
*/
#define OS_ERR_NONE                     0u
#define OS_ERR_PNAME_NULL              12u

#define OS_ERR_CREATE_ISR              16u
#define OS_ERR_NAME_GET_ISR            17u
#define OS_ERR_NAME_SET_ISR            18u
#define OS_ERR_MEM_INVALID_PART        90u
#define OS_ERR_MEM_INVALID_BLKS        91u
#define OS_ERR_MEM_INVALID_SIZE        92u
#define OS_ERR_MEM_FULL                94u
#define OS_ERR_MEM_NO_FREE_BLKS        93u
#define OS_ERR_MEM_INVALID_PBLK        95u
#define OS_ERR_MEM_INVALID_PMEM        96u
#define OS_ERR_MEM_INVALID_ADDR        98u

#endif//include header


malloc.c

/*
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*                                            MEMORY MANAGEMENT
*
*                              (c) Copyright 1992-2012, Micrium, Weston, FL
*                                           All Rights Reserved
*
* File    : OS_MEM.C
* By      : Jean J. Labrosse
* Version : V2.92.07
*
* LICENSING TERMS:
* ---------------
*   uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using  uC/OS-II  in a commercial product you need to contact Micrium to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II.   The fact that the  source is provided does  NOT  mean that you can use it without  paying a
* licensing fee.
*********************************************************************************************************
*/

#define  MICRIUM_SOURCE

#include<stdio.h>
#ifndef  OS_MASTER_FILE
#include"malloc.h"
#endif


OS_MEM           * OSMemFreeList;            /* Pointer to free list of memory partitions       */
OS_MEM            OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager            */

OS_MEM *mem;
INT8U buff[nblock][blockSize];
#if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
/*
*********************************************************************************************************
*                                      CREATE A MEMORY PARTITION
*
* Description : Create a fixed-sized memory partition that will be managed by uC/OS-II.
*
* Arguments   : addr     is the starting address of the memory partition
*
*               nblks    is the number of memory blocks to create from the partition.
*
*               blksize  is the size (in bytes) of each block in the memory partition.
*
*               perr     is a pointer to a variable containing an error message which will be set by
*                        this function to either:
*
*                        OS_ERR_NONE              if the memory partition has been created correctly.
*                        OS_ERR_MEM_INVALID_ADDR  if you are specifying an invalid address for the memory
*                                                 storage of the partition or, the block does not align
*                                                 on a pointer boundary
*                        OS_ERR_MEM_INVALID_PART  no free partitions available
*                        OS_ERR_MEM_INVALID_BLKS  user specified an invalid number of blocks (must be >= 2)
*                        OS_ERR_MEM_INVALID_SIZE  user specified an invalid block size
*                                                   - must be greater than the size of a pointer
*                                                   - must be able to hold an integral number of pointers
* Returns    : != (OS_MEM *)0  is the partition was created
*              == (OS_MEM *)0  if the partition was not created because of invalid arguments or, no
*                              free partition is available.
*********************************************************************************************************
*/

INT8U  OS_StrLen (INT8U *psrc)
{
    INT8U  len;


#if OS_ARG_CHK_EN > 0u
    if (psrc == (INT8U *)0) {
        return (0u);
    }
#endif

    len = 0u;
    while (*psrc != OS_ASCII_NUL) {
        psrc++;
        len++;
    }
    return (len);
}

void  OS_MemClr (INT8U  *pdest,INT16U  size)
{
    while (size > 0u) {
        *pdest++ = (INT8U)0;
        size--;
    }
}

OS_MEM  *OSMemCreate (void   *addr,
                      INT32U  nblks,
                      INT32U  blksize,
                      INT8U  *perr)
{
    OS_MEM    *pmem;
    INT8U     *pblk;
    void     **plink;
    INT32U     loops;
    INT32U     i;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_MEM *)0);
    }
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_MEM *)0);
    }
#endif

#if OS_ARG_CHK_EN > 0u
    if (addr == (void *)0) {                          /* Must pass a valid address for the memory part.*/
        *perr = OS_ERR_MEM_INVALID_ADDR;
        return ((OS_MEM *)0);
    }
    if (((INT32U)addr & (sizeof(void *) - 1u)) != 0u){  /* Must be pointer size aligned                */
        *perr = OS_ERR_MEM_INVALID_ADDR;
        return ((OS_MEM *)0);
    }
    if (nblks < 2u) {                                 /* Must have at least 2 blocks per partition     */
        *perr = OS_ERR_MEM_INVALID_BLKS;
        return ((OS_MEM *)0);
    }
    if (blksize < sizeof(void *)) {                   /* Must contain space for at least a pointer     */
        *perr = OS_ERR_MEM_INVALID_SIZE;
        return ((OS_MEM *)0);
    }
#endif
    pmem = OSMemFreeList;                             /* Get next free memory partition                */
    if (OSMemFreeList != (OS_MEM *)0) {               /* See if pool of free partitions was empty      */
        OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
    }
    if (pmem == (OS_MEM *)0) {                        /* See if we have a memory partition             */
        *perr = OS_ERR_MEM_INVALID_PART;
        return ((OS_MEM *)0);
    }
    plink = (void **)addr;                            /* Create linked list of free memory blocks      */
    pblk  = (INT8U *)addr;
    loops  = nblks - 1u;
    for (i = 0u; i < loops; i++) {
        pblk +=  blksize;                             /* Point to the FOLLOWING block                  */
       *plink = (void  *)pblk;                        /* Save pointer to NEXT block in CURRENT block   */
        plink = (void **)pblk;                        /* Position to  NEXT      block                  */
    }
    *plink              = (void *)0;                  /* Last memory block points to NULL              */
    pmem->OSMemAddr     = addr;                       /* Store start address of memory partition       */
    pmem->OSMemFreeList = addr;                       /* Initialize pointer to pool of free blocks     */
    pmem->OSMemNFree    = nblks;                      /* Store number of free blocks in MCB            */
    pmem->OSMemNBlks    = nblks;
    pmem->OSMemBlkSize  = blksize;                    /* Store block size of each memory blocks        */
    *perr               = OS_ERR_NONE;
    return (pmem);
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                         GET A MEMORY BLOCK
*
* Description : Get a memory block from a partition
*
* Arguments   : pmem    is a pointer to the memory partition control block
*
*               perr    is a pointer to a variable containing an error message which will be set by this
*                       function to either:
*
*                       OS_ERR_NONE             if the memory partition has been created correctly.
*                       OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller
*                       OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
*
* Returns     : A pointer to a memory block if no error is detected
*               A pointer to NULL if an error is detected
*********************************************************************************************************
*/

void  *OSMemGet (OS_MEM  *pmem,INT8U   *perr)
{
    void      *pblk;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((void *)0);
    }
#endif

#if OS_ARG_CHK_EN > 0u
    if (pmem == (OS_MEM *)0) {                        /* Must point to a valid memory partition        */
        *perr = OS_ERR_MEM_INVALID_PMEM;
        return ((void *)0);
    }
#endif
    if (pmem->OSMemNFree > 0u) {                      /* See if there are any free memory blocks       */
        pblk                = pmem->OSMemFreeList;    /* Yes, point to next free memory block          */
        pmem->OSMemFreeList = *(void **)pblk;         /*      Adjust pointer to new free list          */
        pmem->OSMemNFree--;                           /*      One less memory block in this partition  */
        *perr = OS_ERR_NONE;                          /*      No error                                 */
        return (pblk);                                /*      Return memory block to caller            */
    }
    *perr = OS_ERR_MEM_NO_FREE_BLKS;                  /* No,  Notify caller of empty memory partition  */
    return ((void *)0);                               /*      Return NULL pointer to caller            */
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                 GET THE NAME OF A MEMORY PARTITION
*
* Description: This function is used to obtain the name assigned to a memory partition.
*
* Arguments  : pmem      is a pointer to the memory partition
*
*              pname     is a pointer to a pointer to an ASCII string that will receive the name of the memory partition.
*
*              perr      is a pointer to an error code that can contain one of the following values:
*
*                        OS_ERR_NONE                if the name was copied to 'pname'
*                        OS_ERR_MEM_INVALID_PMEM    if you passed a NULL pointer for 'pmem'
*                        OS_ERR_PNAME_NULL          You passed a NULL pointer for 'pname'
*                        OS_ERR_NAME_GET_ISR        You called this function from an ISR
*
* Returns    : The length of the string or 0 if 'pmem' is a NULL pointer.
*********************************************************************************************************
*/

#if OS_MEM_NAME_EN > 0u
INT8U  OSMemNameGet (OS_MEM   *pmem,
                     INT8U   **pname,
                     INT8U    *perr)
{
    INT8U      len;
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return (0u);
    }
#endif

#if OS_ARG_CHK_EN > 0u
    if (pmem == (OS_MEM *)0) {                   /* Is 'pmem' a NULL pointer?                          */
        *perr = OS_ERR_MEM_INVALID_PMEM;
        return (0u);
    }
    if (pname == (INT8U **)0) {                  /* Is 'pname' a NULL pointer?                         */
        *perr = OS_ERR_PNAME_NULL;
        return (0u);
    }
#endif
    *pname = pmem->OSMemName;
    len    = OS_StrLen(*pname);
    *perr  = OS_ERR_NONE;
    return (len);
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                                 ASSIGN A NAME TO A MEMORY PARTITION
*
* Description: This function assigns a name to a memory partition.
*
* Arguments  : pmem      is a pointer to the memory partition
*
*              pname     is a pointer to an ASCII string that contains the name of the memory partition.
*
*              perr      is a pointer to an error code that can contain one of the following values:
*
*                        OS_ERR_NONE                if the name was copied to 'pname'
*                        OS_ERR_MEM_INVALID_PMEM    if you passed a NULL pointer for 'pmem'
*                        OS_ERR_PNAME_NULL          You passed a NULL pointer for 'pname'
*                        OS_ERR_MEM_NAME_TOO_LONG   if the name doesn't fit in the storage area
*                        OS_ERR_NAME_SET_ISR        if you called this function from an ISR
*
* Returns    : None
*********************************************************************************************************
*/

#if OS_MEM_NAME_EN > 0u
void  OSMemNameSet (OS_MEM  *pmem,
                    INT8U   *pname,
                    INT8U   *perr)
{
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#ifdef OS_SAFETY_CRITICAL
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

#if OS_ARG_CHK_EN > 0u
    if (pmem == (OS_MEM *)0) {                   /* Is 'pmem' a NULL pointer?                          */
        *perr = OS_ERR_MEM_INVALID_PMEM;
        return;
    }
    if (pname == (INT8U *)0) {                   /* Is 'pname' a NULL pointer?                         */
        *perr = OS_ERR_PNAME_NULL;
        return;
    }
#endif
    pmem->OSMemName = pname;
    *perr           = OS_ERR_NONE;
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*                                       RELEASE A MEMORY BLOCK
*
* Description : Returns a memory block to a partition
*
* Arguments   : pmem    is a pointer to the memory partition control block
*
*               pblk    is a pointer to the memory block being released.
*
* Returns     : OS_ERR_NONE              if the memory block was inserted into the partition
*               OS_ERR_MEM_FULL          if you are returning a memory block to an already FULL memory
*                                        partition (You freed more blocks than you allocated!)
*               OS_ERR_MEM_INVALID_PMEM  if you passed a NULL pointer for 'pmem'
*               OS_ERR_MEM_INVALID_PBLK  if you passed a NULL pointer for the block to release.
*********************************************************************************************************
*/

INT8U  OSMemPut (OS_MEM  *pmem,
                 void    *pblk)
{
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#if OS_ARG_CHK_EN > 0u
    if (pmem == (OS_MEM *)0) {                   /* Must point to a valid memory partition             */
        return (OS_ERR_MEM_INVALID_PMEM);
    }
    if (pblk == (void *)0) {                     /* Must release a valid block                         */
        return (OS_ERR_MEM_INVALID_PBLK);
    }
#endif
    if (pmem->OSMemNFree >= pmem->OSMemNBlks) {  /* Make sure all blocks not already returned          */
        return (OS_ERR_MEM_FULL);
    }
    *(void **)pblk      = pmem->OSMemFreeList;   /* Insert released block into free block list         */
    pmem->OSMemFreeList = pblk;
    pmem->OSMemNFree++;                          /* One more memory block in this partition            */
    return (OS_ERR_NONE);                        /* Notify caller that memory block was released       */
}
/*$PAGE*/
/*
*********************************************************************************************************
*                                       QUERY MEMORY PARTITION
*
* Description : This function is used to determine the number of free memory blocks and the number of
*               used memory blocks from a memory partition.
*
* Arguments   : pmem        is a pointer to the memory partition control block
*
*               p_mem_data  is a pointer to a structure that will contain information about the memory
*                           partition.
*
* Returns     : OS_ERR_NONE               if no errors were found.
*               OS_ERR_MEM_INVALID_PMEM   if you passed a NULL pointer for 'pmem'
*               OS_ERR_MEM_INVALID_PDATA  if you passed a NULL pointer to the data recipient.
*********************************************************************************************************
*/

#if OS_MEM_QUERY_EN > 0u
INT8U  OSMemQuery (OS_MEM       *pmem,
                   OS_MEM_DATA  *p_mem_data)
{
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0u;
#endif



#if OS_ARG_CHK_EN > 0u
    if (pmem == (OS_MEM *)0) {                   /* Must point to a valid memory partition             */
        return (OS_ERR_MEM_INVALID_PMEM);
    }
    if (p_mem_data == (OS_MEM_DATA *)0) {        /* Must release a valid storage area for the data     */
        return (OS_ERR_MEM_INVALID_PDATA);
    }
#endif

    p_mem_data->OSAddr     = pmem->OSMemAddr;
    p_mem_data->OSFreeList = pmem->OSMemFreeList;
    p_mem_data->OSBlkSize  = pmem->OSMemBlkSize;
    p_mem_data->OSNBlks    = pmem->OSMemNBlks;
    p_mem_data->OSNFree    = pmem->OSMemNFree;
    p_mem_data->OSNUsed    = p_mem_data->OSNBlks - p_mem_data->OSNFree;
    return (OS_ERR_NONE);
}
#endif                                           /* OS_MEM_QUERY_EN                                    */
/*$PAGE*/
/*
*********************************************************************************************************
*                                 INITIALIZE MEMORY PARTITION MANAGER
*
* Description : This function is called by uC/OS-II to initialize the memory partition manager.  Your
*               application MUST NOT call this function.
*
* Arguments   : none
*
* Returns     : none
*
* Note(s)    : This function is INTERNAL to uC/OS-II and your application should not call it.
*********************************************************************************************************
*/

void  OS_MemInit (void)
{
#if OS_MAX_MEM_PART == 1u
    OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl));   /* Clear the memory partition table          */
    OSMemFreeList               = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list           */
#if OS_MEM_NAME_EN > 0u
    OSMemFreeList->OSMemName    = (INT8U *)"?";           /* Unknown name                              */
#endif
#endif

#if OS_MAX_MEM_PART >= 2u
    OS_MEM  *pmem;
    INT16U   i;


    OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl));   /* Clear the memory partition table          */
    for (i = 0u; i < (OS_MAX_MEM_PART - 1u); i++) {       /* Init. list of free memory partitions      */
        pmem                = &OSMemTbl[i];               /* Point to memory control block (MCB)       */
        pmem->OSMemFreeList = (void *)&OSMemTbl[i + 1u];  /* Chain list of free partitions             */
#if OS_MEM_NAME_EN > 0u
        pmem->OSMemName  = (INT8U *)(void *)"?";
#endif
    }
    pmem                = &OSMemTbl[i];
    pmem->OSMemFreeList = (void *)0;                      /* Initialize last node                      */
#if OS_MEM_NAME_EN > 0u
    pmem->OSMemName = (INT8U *)(void *)"?";
#endif

    OSMemFreeList   = &OSMemTbl[0];                       /* Point to beginning of free list           */
#endif
}



void  free(void *memb)
{
    OSMemPut(mem,memb);
}
void *malloc(INT8U size)
{    
    INT8U perr;
    if(size>blockSize)return 0;
    return OSMemGet(mem,&perr);
}

void meminit(void)
{
    OS_MemInit();
    INT8U err;
    mem = OSMemCreate(buff,nblock,blockSize,&err);
    #ifdef debug
    printf("in meminit perr =%d\n",err);
    #endif
}#endif                                                    /* OS_MEM_EN                                 */

vector.h  //相当于stl中的list

# ifndef __vector_H__
# define __vector_H__

# include <stdio.h>  
#include"malloc.h"
# include <string.h>  

# define MIN_LEN         256
# define CVEFAILED  -1
# define CVESUCCESS  0
# define CVEPUSHBACK 1
# define CVEPOPBACK  2
# define CVEINSERT   3
# define CVERM       4
# define EXPANED_VAL 1
# define REDUSED_VAL 2

typedef void *iterator;
typedef struct _vector *vector;


# ifdef __cplusplus
extern "C" {
# endif

    vector    list_create   (const size_t size                           );//数据类型 及其大小
    void      list_destroy  (const vector cv                            );
    size_t    list_length   (const vector cv                            );
    int       list_pushback (const vector cv, void *memb                );
    int       list_popback  (const vector cv                );
    iterator  list_begin    (const vector cv                            );
    iterator  list_end      (const vector cv                            );
    iterator  list_next     (const vector cv, iterator iter            );
    int       list_val_at   (const vector cv, size_t index, void *memb  );
    int       list_remove   (const vector cv,void *memb);
    int list_rm_at(const vector cv, size_t index);
    int       list_insert_at(const vector cv, size_t index, void *memb);
    
    //比较两个内存是否相同  相同 返回1 否则 返回0
    int compare_memb(const void *memb1,const void *memb2,int size);

    /* for test  */
    void      cv_info          (const vector cv                            );
    void      cv_print         (const vector cv                            );

# ifdef __cplusplus
}
# endif

#endif /* EOF file vector.h */

vector.c

#include "vector.h"

#ifndef __gnu_linux__
#define __func__ "unknown"
#define inline __forceinline
#endif

# define CWARNING_ITER(cv, iter, file, func, line) \
    do {\
    if ((vector_begin(cv) > iter) || (vector_end(cv) <= iter)) {\
    fprintf(stderr, "var(" #iter ") warng out of range, "\
    "at file:%s func:%s line:%d!!\n", file, func, line);\
    return CVEFAILED;\
    }\
    } while (0)
typedef struct _vector_node
{
    void *data;
    struct _vector_node *next;
}vectornode;



struct _vector
{
    vectornode *head;
    size_t cv_len,datatype_size;
};



vector list_create(const size_t size)
{
    vector cv = (vector)malloc(sizeof (struct _vector));

    if (!cv) return NULL;

    cv->datatype_size =size;
    cv->head=NULL;
    cv->cv_len = 0;
    return cv;
}  


void list_destroy(const vector cv)  
{  
    vectornode *pvn=cv->head;
    while(pvn!=NULL)
    {
        free(pvn);
        free(pvn->data);
        pvn=pvn->next;
    }
    return;  
}  

size_t list_length(const vector cv)  
{  
    return cv->cv_len;  
}  

int list_pushback(const vector cv, void *memb)  //添加数据
{
    vectornode* pvn=(vectornode*)malloc(sizeof(vectornode));
    if(pvn==NULL){free(pvn);return CVEPUSHBACK;}//压入错误
    pvn->data=malloc(cv->datatype_size);
    memcpy( pvn->data,memb,cv->datatype_size);
    pvn->next=NULL;
    vectornode*pnode=cv->head;

    cv->cv_len++;
    //当里面没值   放入第一个值
    if(pnode==NULL)
      {
        cv->head=pvn;
        return CVESUCCESS;
      }
       
    while(pnode->next!=NULL)
    {
        pnode=pnode->next;
    }
    
    pnode->next=pvn;

    return CVESUCCESS;  
}  

int list_popback(const vector cv)  
{  
    if (cv->cv_len <= 0) //当没有  
     return CVEPOPBACK;  

    vectornode *p=cv->head;

    
    //当只有一个元素时
    
    if(p->next==NULL)
    {
        free(p->data);
        free(p);
        cv->head=NULL;
        cv->cv_len--;
        return CVESUCCESS;  
    }
    
    //当多个元素时 找到 末尾那个元素  
    while(p->next->next!=NULL)
    {
        p=p->next;
    }
    free(p->next->data);
    free(p->next);
    p->next=NULL;
    
    cv->cv_len--;

    return CVESUCCESS;  
}  



 

iterator list_begin(const vector cv)  
{  
    return cv->head->data;  
}  

iterator list_end(const vector cv)  
{  
    vectornode *pnode=cv->head;
    if(pnode==NULL)
       return 0;
    while(pnode->next!=NULL)
    {
        pnode=pnode->next;
    }
    return pnode->data;  
}  


int list_insert_at(const vector cv, size_t index, void *memb)
{  
    if(memb==NULL){return 1;}//插入值不为空
    
    if(index>cv->cv_len)return 1;//插入位置 在0.1.2.3.4.。。。。cv->cv_len
    
    vectornode *pnode=cv->head,*node=(vectornode*)malloc(sizeof(vectornode));
    if(node==NULL)return 1;
    node->data=malloc(cv->datatype_size);
    if(node->data==NULL)return 1;
    memcpy(node->data,memb,cv->datatype_size);
    
    //当插入的是 第一个
    if(index==0)    
    {
        node->next=cv->head;
        cv->head=node;
        printf("insert 0 position\n");
        return 0;
     }
    
    //
    index--;
    while(index)
    {
        index--;
        pnode=pnode->next;
    }
    
    //当在 末尾位置时候
    node->next=cv->head->next;
    pnode->next=node;
    
    return 0;  
}  
 


 

int list_rm_at(const vector cv, size_t index)  
{  
    if(index>=cv->cv_len)return 1;//不能大于等于 长度  因为从0开始
    
    vectornode* pnode=(cv->head);//最起码满足 状况
    
    //when the index value is 0 and there two condition ,one is the list only have one data,two is more than one data!

   cv->cv_len--;
    //当 移除的是 第一个0位置
    if(index==0)
    {
        free(cv->head->data);
        free(cv->head);
        cv->head=cv->head->next;
        return 0;
     }
    
     //移除1 2,3 4.......的位置  
     index--;
    while(index)
    {
        index--;
          pnode=pnode->next;
    }
    
    //当移除的是最后一个
    free(pnode->next->data);
    free(pnode->next);
    pnode->next=pnode->next->next;
    
    return 0;  
}  

int list_val_at(const vector cv, size_t index, void *memb)//start by zero
{
    if(memb==NULL)return 1;
    if(index>=cv->cv_len)return 1;
    
    vectornode* pnode=cv->head;
    while(index)
    {
        pnode=pnode->next;
        index--;
    }
    
    memcpy(memb,pnode->data,cv->datatype_size);
}

int    list_remove(const vector cv,void *memb)//成功0
{
    vectornode *pnode=cv->head;//当前的cnode 和先前的pnode
    if(memb==NULL||pnode==NULL)return 1;
    
    if(cv->cv_len<=0)return 1;
    
    //找到  值为 memb的并把 它的值 移除
    //当只有一个 内存的时候
    //当为第一个的时候。。
    if(compare_memb(memb,pnode->data,cv->datatype_size))
    {
           free(pnode->data);
         free(pnode);
         cv->head=cv->head->next;
         return 0;
    }else
    printf("llist_remove not equal\n");
    
    //当为 后面的1,2.3.4.5.。。。。。
    while(pnode->next!=NULL)
    {
        if(compare_memb(memb,pnode->next->data,cv->datatype_size))
        {
               free(pnode->next->data);
             free(pnode->next);
             pnode->next=pnode->next->next;
             return 0;
        }
        pnode=pnode->next;
    }
    return 1;
}

int     compare_memb(const void *memb1,const void *memb2,int size)
{
    unsigned char*p1=(unsigned char*)memb1;
    unsigned char *p2=(unsigned char*)memb2;
    while(size)
    {
        #ifdef debug
        printf("size=%d\n",size);
        #endif
        if((*p1)!=(*p2))return 0;
        p1++;
        p2++;
        size--;
    }
    
    return 1;
}


main.c

//主函数

#include <stdio.h>
#include"malloc.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#include "vector.h"

typedef struct _mov{
        int x;
        int y;
    }mov;



int main()
{
    meminit();
    mov i={2,3};
    mov *mv;
    
    mov mv1;
    vector cv = list_create(sizeof(mov));
    list_pushback(cv,&i);
    i.x=11;
    i.y=12;
    list_pushback(cv,&i);
    i.x=30;
    list_pushback(cv,&i);
    i.y=100;
    list_pushback(cv,&i);
    i.x=100;
    list_pushback(cv,&i);
    //list_insert_at(cv,0,&i);
    
    
    //cv_print(cv);
    for(int i=0;i<=4;i++){
    
    list_val_at(cv,i,&mv1);
    printf("x==%d,y==%d\n",mv1.x,mv1.y);
   }
   printf("=========================================================================\n");
   //mv=(mov*)list_end(cv);
   //printf("x=%d,y=%d\n",mv->x,mv->y);
   //list_insert_at  这个函数有点问题
   
    i.x=300;
    i.y=400;
    list_insert_at(cv,0,&i);
       for(int i=0;i<=5;i++){
    
    list_val_at(cv,i,&mv1);
    printf("x==%d,y==%d\n",mv1.x,mv1.y);
   }
   printf("=========================================================================\n");
   
    list_destroy(cv);
    
    
    
    printf("others-----------===============================================\n");
    int a1=4,b1=4;
    mov mv3={2,3},mv2={2,3};
    printf("struct mov size=%d\n",sizeof(mov));
    if(compare_memb(&mv3,&mv2,sizeof(mov)))printf("equal\n");
    else printf("not equal");
    return 0;
}

/*
int main()
{
    int *x1,*x2;
    x1=malloc(sizeof(int));
    x2=malloc(sizeof(int));
    free(x2);
    printf("%d,%d,%d",x1,x2,x2);
}

*/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值