由于写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);
}
*/