[an error occurred while processing this directive] [an error occurred while processing this directive]
Ответ:
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)
[an error occurred while processing this directive] [an error occurred while processing this directive] [an error occurred while processing this directive]

Отправлено Romario 07 декабря 2001 г. 12:27
В ответ на: Хочу malloc для Ht-pic(+) отправлено abivan 07 декабря 2001 г. 12:01

Если есть желание, поковыряйся в моей malloc :) работает, но не знаю как это все будет выглядеть для PIC :)


/*-------- program files ----------------------------------------------------*/
#include "sa_string.h"
#include "sa_stdlib.h"

//u8_t Heap[16000];
__declspec (big_array) u8_t Heap[/*64*/32000];

//__declspec (big_array) u8_t Heap[6];


/*-------- context ----------------------------------------------------------*/
/*
* Flag to be used for indicating that a memory segment is free or occupied.
*/
#define MEMSEGM_FREE 0x1

/* Descriptor for a segment of memory. */
typedef struct memsegm {
struct memsegm *PrvMemSegmPtr; /* Pointer to prev. segment */
struct memsegm *NxtMemSegmPtr; /* Pointer to next segment */
u32_t Misc; /* Length and flags */
} MemSegm_t;
typedef MemSegm_t *pMemSegm_t;

/* Overhead per memory segment. */
#define MEMSEGM_OVERHEAD sizeof (MemSegm_t)

/*-------- data declarations ------------------------------------------------*/
/*
* Define pointer to start of global variable area.
*/

/* Heap variables.*/
static u32_t G_hstart;
static u32_t G_hend;

/* Pointer to first memory segment in chain.*/
static pMemSegm_t G_start_list_ptr = NULL;

/*-------- function prototypes ----------------------------------------------*/
/*-------- macros -----------------------------------------------------------*/
/*
* Macro's to set/get length and flags in miscellaneous field.
*/
#define SET_LENGTH(m, l) \
(m = ((u32_t) (l) << 8) | (m & 0x000000ff))

#define LENGTH(m) \
((m) >> 8)

#define SET_FLAGS(m, f) \
(m = ((u32_t) (f) & 0x000000ff) | (m & 0xffffff00))

#define FLAGS(m) \
((m) & 0x000000ff)

/*
* Get memory pointer from segment pointer and vice versa.
*/
#define MEM_PTR(memsegm_ptr) \
((void *) ((u8_t *) memsegm_ptr + MEMSEGM_OVERHEAD))

#define MSM_PTR(mem_ptr) \
((pMemSegm_t) ((u8_t *) mem_ptr - MEMSEGM_OVERHEAD))

/*
* Round integer upwards to nearest multiple of 4.
*/
#define UP_LONG_ALIGN(u) \
((u) % 4 == 0 ? (u) : (((u) / 4) * 4) + 4)

/*
* Check memory segment
*/
#if 0
#define CHECK_MEMSEGM(m,s) ___CheckSegm(m,s)
#else
#define CHECK_MEMSEGM(m,s)
#endif


/******************************************************************************
* PRIVATE FUNCTION DEFINITIONS
*****************************************************************************/
/******************************************************************************
* DESCRIPTION:
* Check if memory segment is not corrupt.
*****************************************************************************/
#if 0
static void
___CheckSegm( pMemSegm_t memsegm_ptr, char *s)
{
u16_t corrupt = 0;

u8_t *hstart = (u8_t *) G_hstart;
u8_t *hend = (u8_t *) G_hend;

static pMemSegm_t prev_memsegm_ptr=NULL;

if (memsegm_ptr != NULL) {
if (memsegm_ptr->NxtMemSegmPtr != NULL) {
if (((u32_t) memsegm_ptr->NxtMemSegmPtr - (u32_t) memsegm_ptr) !=
(LENGTH (memsegm_ptr->Misc) + MEMSEGM_OVERHEAD)) {
TrmPrintf((pu8_t)"\nCheck memory segment failed\n");
TrmPrintf((pu8_t)"\nCorrupt NxtMemSegmPtr or Length\n");
TrmPrintf((pu8_t)"Memory corrupt at %08lxh:\n", (u32_t) memsegm_ptr);
TrmPrintf((pu8_t)"------------------------\n");
TrmPrintf((pu8_t)"->MemSegmPtr = %08lxh\n", (u32_t) memsegm_ptr);
TrmPrintf((pu8_t)"->NxtMemSegmPtr = %08lxh\n",
(u32_t) memsegm_ptr->NxtMemSegmPtr );
TrmPrintf((pu8_t)"->PrvMemSegmPtr = %08lxh\n",
(u32_t) memsegm_ptr->PrvMemSegmPtr );
TrmPrintf((pu8_t)"->Length = %06lxh\n", LENGTH (memsegm_ptr->Misc));
TrmPrintf((pu8_t)"->Flags = %02lxh\n", FLAGS (memsegm_ptr->Misc));
TrmPrintf((pu8_t)"Descr: %s\n", s);
TrmPrintf((pu8_t)"Previous memsegm pointer:\n");
TrmPrintf((pu8_t)"------------------------\n");
TrmPrintf((pu8_t)"->MemSegmPtr = %08lxh\n", (u32_t) prev_memsegm_ptr);
TrmPrintf((pu8_t)"->NxtMemSegmPtr = %08lxh\n",
(u32_t) prev_memsegm_ptr->NxtMemSegmPtr );
TrmPrintf((pu8_t)"->PrvMemSegmPtr = %08lxh\n",
(u32_t) prev_memsegm_ptr->PrvMemSegmPtr );
TrmPrintf((pu8_t)"->Length = %06lxh\n", LENGTH ( prev_memsegm_ptr->Misc));
TrmPrintf((pu8_t)"->Flags = %02lxh\n", FLAGS ( prev_memsegm_ptr->Misc));
corrupt=1;
}
}

if ((LENGTH (memsegm_ptr->Misc) + MEMSEGM_OVERHEAD +
(u32_t) memsegm_ptr) > ((u32_t) hend)) {
TrmPrintf((pu8_t)"\nCheck memory segment failed\n");
TrmPrintf((pu8_t)"\nCorrupt Length\n");
corrupt=1;
}

if (memsegm_ptr->PrvMemSegmPtr != NULL) {
if ( ( ((u32_t)memsegm_ptr->PrvMemSegmPtr) > ((u32_t) hend)) ||
( ((u32_t)memsegm_ptr->PrvMemSegmPtr) < ((u32_t) hstart)) ) {
TrmPrintf((pu8_t)"\nCheck memory segment failed\n");
TrmPrintf((pu8_t)"\nCorrupt PrvMemSegmPtr\n");
corrupt=1;
} else {
if (memsegm_ptr != memsegm_ptr->PrvMemSegmPtr->NxtMemSegmPtr) {
TrmPrintf((pu8_t)"\nCheck memory segment failed\n");
TrmPrintf((pu8_t)"\nCorrupt PrvMemSegmPtr or memsegm_ptr->PrvMemSegmPtr->NxtMemSegmPtr\n");
corrupt=1;
}
}
}
}

if (corrupt) {
TrmPrintf((pu8_t)"Memory corrupt at %08lxh:\n", (u32_t) memsegm_ptr);
TrmPrintf((pu8_t)"------------------------\n");
TrmPrintf((pu8_t)"->MemSegmPtr = %08lxh\n", (u32_t) memsegm_ptr);
TrmPrintf((pu8_t)"->NxtMemSegmPtr = %08lxh\n",
(u32_t) memsegm_ptr->NxtMemSegmPtr );
TrmPrintf((pu8_t)"->PrvMemSegmPtr = %08lxh\n",
(u32_t) memsegm_ptr->PrvMemSegmPtr );
TrmPrintf((pu8_t)"->Length = %06lxh\n", LENGTH (memsegm_ptr->Misc));
TrmPrintf((pu8_t)"->Flags = %02lxh\n", FLAGS (memsegm_ptr->Misc));
TrmPrintf((pu8_t)"Descr: %s\n", s);

TrmPrintf((pu8_t)"Previous memsegm pointer:\n");
TrmPrintf((pu8_t)"------------------------\n");
TrmPrintf((pu8_t)"->MemSegmPtr = %08lxh\n", (u32_t) prev_memsegm_ptr);
TrmPrintf((pu8_t)"->NxtMemSegmPtr = %08lxh\n",
(u32_t) prev_memsegm_ptr->NxtMemSegmPtr );
TrmPrintf((pu8_t)"->PrvMemSegmPtr = %08lxh\n",
(u32_t) prev_memsegm_ptr->PrvMemSegmPtr );
TrmPrintf((pu8_t)"->Length = %06lxh\n", LENGTH ( prev_memsegm_ptr->Misc));
TrmPrintf((pu8_t)"->Flags = %02lxh\n", FLAGS ( prev_memsegm_ptr->Misc));
}

prev_memsegm_ptr = memsegm_ptr;
}
#endif

/******************************************************************************
* DESCRIPTION:
* Create header in memory just before actual memory reserved by sa_malloc ().
*****************************************************************************/
static pMemSegm_t
___CreateHdr ( u8_t *addr,
pMemSegm_t prv_memsegm,
pMemSegm_t nxt_memsegm,
u32_t length,
u8_t flags
)
{

*(TO_LONG_PTR(addr) + 0) = (u32_t) prv_memsegm;
*(TO_LONG_PTR(addr) + 1) = (u32_t) nxt_memsegm;
*(TO_LONG_PTR(addr) + 2) = (length << 8) | (u32_t) flags;

return ((pMemSegm_t) addr);
}

/******************************************************************************
* DESCRIPTION:
* This function should be called once when initializing this package. It
* creates an initial memory segment header for the total amount of RAM
* available to the heap.
*****************************************************************************/
static void
___Init (void)
{
/* Initialize global heap boundary variables */
G_hstart = (u32_t)&Heap;
G_hend = G_hstart + sizeof(Heap);

/*
* Create initial list entry. Note that the size is rounded down to a
* multiple of 4 (longword boundary).
*/
G_start_list_ptr = ___CreateHdr( TO_BYTE_PTR(G_hstart),
NULL,
NULL,
((G_hend - G_hstart - MEMSEGM_OVERHEAD) / 4) * 4,
MEMSEGM_FREE
);
CHECK_MEMSEGM(G_start_list_ptr,"___Init");

}

/******************************************************************************
* DESCRIPTION:
* Create an extra segment in specified segment. The second argument specifies
* the amount of memory used in the first of the two segments.
*****************************************************************************/
static void
___InsertMemSegm (pMemSegm_t memsegm_ptr, u32_t occ_size)
{
pMemSegm_t new_memsegm_ptr;

CHECK_MEMSEGM(memsegm_ptr,"___InsertMemSegm:start");

/* Create haeder for new segment */
new_memsegm_ptr = ___CreateHdr (
(u8_t *) MEM_PTR (memsegm_ptr) + occ_size,
(pMemSegm_t) memsegm_ptr,
memsegm_ptr->NxtMemSegmPtr ? memsegm_ptr->NxtMemSegmPtr : NULL,
LENGTH (memsegm_ptr->Misc) - occ_size - MEMSEGM_OVERHEAD,
MEMSEGM_FREE);

/* Correct chain */
if (memsegm_ptr->NxtMemSegmPtr) {
memsegm_ptr->NxtMemSegmPtr->PrvMemSegmPtr = new_memsegm_ptr;
}
memsegm_ptr->NxtMemSegmPtr = new_memsegm_ptr;

/* Adapt size of current segment */
SET_LENGTH (memsegm_ptr->Misc, occ_size);
CHECK_MEMSEGM(memsegm_ptr,"___InsertMemSegm:end1");
CHECK_MEMSEGM(memsegm_ptr->NxtMemSegmPtr,"___InsertMemSegm:end2");
}

/******************************************************************************
* DESCRIPTION:
* Free memory segment. This means setting the free flag in the header and
* scanning the memory chain backwards as well as forwards to compact adjacent
* free areas. The resulting free segment pointer is returned.
*****************************************************************************/
static pMemSegm_t
___FreeMemSegm (pMemSegm_t memsegm_ptr)
{
pMemSegm_t free_memsegm_ptr,
prv_free_memsegm_ptr;

CHECK_MEMSEGM(memsegm_ptr,"___FreeMemSegm:start");
SET_FLAGS (memsegm_ptr->Misc, FLAGS (memsegm_ptr->Misc) | MEMSEGM_FREE);

free_memsegm_ptr = memsegm_ptr->PrvMemSegmPtr;
prv_free_memsegm_ptr = memsegm_ptr;

/* Search backwards for free segments */
while ((free_memsegm_ptr) &&
((FLAGS (free_memsegm_ptr->Misc) & MEMSEGM_FREE) != 0))
{
/*
* Increment length of previous segment with length of segment to be freed.
*/
SET_LENGTH (free_memsegm_ptr->Misc,
LENGTH (free_memsegm_ptr->Misc) +
MEMSEGM_OVERHEAD +
LENGTH (free_memsegm_ptr->NxtMemSegmPtr->Misc));

/*
* Let previous segment point to first one after segment which is being
* freed.
*/
free_memsegm_ptr->NxtMemSegmPtr = memsegm_ptr->NxtMemSegmPtr;

/* Repeat for previous segment.*/
prv_free_memsegm_ptr = free_memsegm_ptr;
free_memsegm_ptr = free_memsegm_ptr->PrvMemSegmPtr;
}

if (memsegm_ptr->NxtMemSegmPtr) {
/* Adapt previous pointer of first segment after segment to be freed */
memsegm_ptr->NxtMemSegmPtr->PrvMemSegmPtr = prv_free_memsegm_ptr;

memsegm_ptr = prv_free_memsegm_ptr;
free_memsegm_ptr = memsegm_ptr->NxtMemSegmPtr;

/* Search forward for free segments */
while ((free_memsegm_ptr) &&
((FLAGS (free_memsegm_ptr->Misc) & MEMSEGM_FREE) != 0)) {

/* Correct pointers in next segment.*/
memsegm_ptr->NxtMemSegmPtr =
free_memsegm_ptr->NxtMemSegmPtr;
/*
* Increment length of current segment with length of segment to be
* freed. This has to be done before the link to the next segment is
* changed.
*/
SET_LENGTH (memsegm_ptr->Misc,
LENGTH (memsegm_ptr->Misc) +
MEMSEGM_OVERHEAD +
LENGTH (free_memsegm_ptr->Misc));
/*
* Repeat for next segment.
*/
free_memsegm_ptr = free_memsegm_ptr->NxtMemSegmPtr;
}
if (free_memsegm_ptr)
memsegm_ptr->NxtMemSegmPtr->PrvMemSegmPtr = memsegm_ptr;
CHECK_MEMSEGM(memsegm_ptr,"___FreeMemSegm:end1");
return (memsegm_ptr);
} else
{
CHECK_MEMSEGM(prv_free_memsegm_ptr,"___FreeMemSegm:end2");
return (prv_free_memsegm_ptr);
}
}

/******************************************************************************
* DESCRIPTION:
* Find first free segment in memory chain large enough to fulfill request.
*****************************************************************************/
static pMemSegm_t
___FindFirstFit (u32_t len)
{
pMemSegm_t list_ptr;

/* Search for first free segment large enough to hold overhead plus data */
list_ptr = G_start_list_ptr;
while ( ((len > LENGTH (list_ptr->Misc)) || !(FLAGS (list_ptr->Misc) & MEMSEGM_FREE)) &&
(list_ptr != NULL)
)
{
CHECK_MEMSEGM(list_ptr,"___FindFirstFit1");
list_ptr = list_ptr->NxtMemSegmPtr;
}

CHECK_MEMSEGM(list_ptr,"___FindFirstFit2");

/* None found */

return(list_ptr);
}

/******************************************************************************
* DESCRIPTION:
* Print chain of memory segments.
*****************************************************************************/
void
DumpMemChain (void)
{
pMemSegm_t list_ptr = G_start_list_ptr;
u32_t total_length = 0;
int i = 0;


TrmPrintf((pu8_t)"\n\r Memory segments list:");
TrmPrintf((pu8_t)"\n\r =====================\n\r");

while (list_ptr)
{
TrmPrintf((pu8_t)"\n\r --------- Memory segment % --------------",i++);
TrmPrintf((pu8_t)"\n\r %xz <- %xz ->%xz",(u32_t)(list_ptr->PrvMemSegmPtr ? list_ptr->PrvMemSegmPtr : 0),
(u32_t) list_ptr,
(u32_t)(list_ptr->NxtMemSegmPtr ? list_ptr->NxtMemSegmPtr : 0));

TrmPrintf((pu8_t)"\n\r ->Length = %x", LENGTH (list_ptr->Misc));
TrmPrintf((pu8_t)"\n\r ->Flags = %x", FLAGS (list_ptr->Misc));

total_length += LENGTH (list_ptr->Misc);
list_ptr = list_ptr->NxtMemSegmPtr;

}

TrmPrintf((pu8_t)"\n\r=====================");
TrmPrintf((pu8_t)"\n\r#segments = %x", (u32_t) i);
TrmPrintf((pu8_t)"\n\rTotal length = %x", total_length);
}


/******************************************************************************
* DESCRIPTION:
* Convert string to number. The base can be specified as 2, 10 or 16.
*****************************************************************************/
static s32_t
___GetScalar (u8_t *data_ptr, s8_t base)
{
u8_t ch;
Bool_t cont;
s32_t result;


/* Skip any leading whitespace */
while (*data_ptr == ' ')
data_ptr++;

/* Go get number */
result = 0;
cont = TRUE;
while (cont && (*data_ptr != '\0')) {
ch = *data_ptr++;

switch (ch) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
result += (ch - '0');
result *= base;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
result += ((ch - 'a') + 10);
result *= base;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
result += ((ch - 'A') + 10);
result *= base;
break;
case '-':
result *= -1;
break;
case '+':
break;
default:
/* Unrecognized character */
cont = FALSE;
break;
}
}

if (!cont) {
return (0);
} else {
result /= base;
return (result);
}
}

/******************************************************************************
* PUBLIC FUNCTION DEFINITIONS
*****************************************************************************/
/******************************************************************************
* DESCRIPTION:
* Allocate contiguous memory of 'size' bytes. Return pointer to memory if
* successfull else return NULL.
*****************************************************************************/

void *
sa_malloc (u32_t size)
{
static int i = 0;
pMemSegm_t memsegm_ptr;
u32_t aligned_size;


aligned_size = UP_LONG_ALIGN (size);
if (!i)
{
i = 1;
___Init ();

}

if (!(memsegm_ptr = ___FindFirstFit (aligned_size))) {
/* DEBUG */
TrmPrintf((pu8_t)"NULL pointer...\n");
return (NULL);
}
else
{
SET_FLAGS (memsegm_ptr->Misc, FLAGS (memsegm_ptr->Misc) & ~MEMSEGM_FREE);
if (LENGTH (memsegm_ptr->Misc) > aligned_size + MEMSEGM_OVERHEAD + ALLOC_THRESHOLD)
{
___InsertMemSegm (memsegm_ptr, aligned_size);
}
return (MEM_PTR (memsegm_ptr));
}
}

/******************************************************************************
* DESCRIPTION:
* Allocate contiguous memory of 'num' elements of 'size' bytes each. The area
* is initialized with zeroes. Return pointer to memory if successfull else
* return NULL.
*****************************************************************************/
void *
sa_calloc (u32_t num, u32_t size)
{
void *p;

p = sa_malloc (num * size);
if (!p) {
/* DEBUG */
TrmPrintf((pu8_t)"NULL pointer...\n");
return (NULL);
} else {
return (sa_memset (p,0, num * size));
}
}

/******************************************************************************
* DESCRIPTION:
* Free allocated memory.
*****************************************************************************/
void
sa_free (void *p)
{
pMemSegm_t memsegm_ptr;

if (p)
{
memsegm_ptr = MSM_PTR (p);



if (((u32_t) memsegm_ptr->NxtMemSegmPtr - (u32_t) memsegm_ptr) != (LENGTH (memsegm_ptr->Misc) + MEMSEGM_OVERHEAD))
{
TrmPrintf ((pu8_t)"\n\r Memory corrupt at %x:", (u32_t) memsegm_ptr);
putchJ(' ');
// Memory corrupt at 0x30559F2

// 03088634 00001000 .big_array ShowPrgTaskStk (main.c)
// 03089634 00001000 .big_array PSIFIFO_TaskStk (main.c)


TrmPrintf ((pu8_t)"\n\r ------------------------");
TrmPrintf ((pu8_t)"\n\r ->MemSegmPtr = %x", (u32_t)(memsegm_ptr ? memsegm_ptr : 0));
TrmPrintf ((pu8_t)"\n\r ->NxtMemSegmPtr = %x", (u32_t) (memsegm_ptr->NxtMemSegmPtr ? memsegm_ptr->NxtMemSegmPtr : 0));
TrmPrintf ((pu8_t)"\n\r ->Length = %x", LENGTH (memsegm_ptr->Misc));
TrmPrintf ((pu8_t)"\n\r ->Flags = %x", FLAGS (memsegm_ptr->Misc));
}

___FreeMemSegm (memsegm_ptr);
}
}

/******************************************************************************
* DESCRIPTION:
* Reallocate memory to requested size.
*****************************************************************************/
void *
sa_realloc (void *p, u32_t size)
{
pMemSegm_t memsegm_ptr, new_memsegm_ptr;
void *q;
u32_t aligned_size;

aligned_size = UP_LONG_ALIGN (size);

if (p) {
memsegm_ptr = MSM_PTR (p);
new_memsegm_ptr = ___FreeMemSegm (memsegm_ptr);
}
else
return (sa_malloc (size));

if ((LENGTH (new_memsegm_ptr->Misc) >= aligned_size) && (new_memsegm_ptr == memsegm_ptr))
{
/* Enough space available.*/
SET_FLAGS (new_memsegm_ptr->Misc, FLAGS (new_memsegm_ptr->Misc) & ~MEMSEGM_FREE);
if (LENGTH (new_memsegm_ptr->Misc) > aligned_size + MEMSEGM_OVERHEAD + ALLOC_THRESHOLD)
{
___InsertMemSegm (new_memsegm_ptr, aligned_size);
}
return (MEM_PTR (new_memsegm_ptr));
}
else
{
/* No adjacent space available. So we just allocate new storage and copy data. */
if (!(q = sa_malloc (size)))
return (NULL);

sa_memcpy (q, p, LENGTH (memsegm_ptr->Misc));
sa_free (p);
return (q);
}
}

/******************************************************************************
* DESCRIPTION:
* Return various statistics of current memory manager configuration.
*****************************************************************************/
void
sa_meminfo (pMemInfo_t mem_info_ptr)
{
pMemSegm_t mem_segm_ptr;

mem_info_ptr->HeapSize = G_hend - G_hstart;
mem_info_ptr->FreeBytes = 0;
mem_info_ptr->AllocBytes = 0;
mem_info_ptr->FreeSegments = 1;
mem_info_ptr->AllocSegments = 0;

mem_segm_ptr = G_start_list_ptr;
while (mem_segm_ptr) {
if ((FLAGS (mem_segm_ptr->Misc)) & MEMSEGM_FREE) {
mem_info_ptr->FreeSegments++;
mem_info_ptr->FreeBytes += LENGTH (mem_segm_ptr->Misc);
} else {
mem_info_ptr->AllocSegments++;
mem_info_ptr->AllocBytes += LENGTH (mem_segm_ptr->Misc);
}
mem_segm_ptr = mem_segm_ptr->NxtMemSegmPtr;
}

#if 1
DumpMemChain ();
#endif
}

/******************************************************************************
* DESCRIPTION:
* Convert string to integer.
*****************************************************************************/
s32_t
sa_atoi (u8_t *s)
{


/* atoi () only converts decimal numbers */
return (___GetScalar (s, 10));
}


/******************************************************************************
* DESCRIPTION:
* Main test function.
*****************************************************************************/



void
TestMalloc (void)
{
#if 0
MemInfo_t mi;
u8_t buf1 [10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
u8_t buf2 [10] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
u8_t *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
u8_t *p9, *p10, *p11, *p12, *p13, *p14, *p15, *p16;

/* Test copy functions */
sa_memcpy (buf2, buf1, 10);
sa_memcpy (buf1, buf1 + 3, 4);
sa_memcpy (buf1, buf2, 10);
sa_memcpy (buf1 + 3, buf1, 4);

/* Test memory management functions */
p1 = (u8_t *) sa_malloc (8);
p2 = (u8_t *) sa_malloc (8);
p3 = (u8_t *) sa_malloc (8);
p4 = (u8_t *) sa_malloc (1000);
p5 = (u8_t *) sa_malloc (8);
p6 = (u8_t *) sa_malloc (8);
p7 = (u8_t *) sa_malloc (8);
p8 = (u8_t *) sa_malloc (1000);
DumpMemChain();
sa_free (p3);
sa_free (p5);
sa_free (p4);
DumpMemChain ();
p9 = (u8_t *) sa_malloc (8);
p10 = (u8_t *) sa_malloc (8);
p11 = (u8_t *) sa_malloc (8);
p12 = (u8_t *) sa_malloc (1000);
p13 = (u8_t *) sa_malloc (8);
p14 = (u8_t *) sa_malloc (8);
p15 = (u8_t *) sa_malloc (8);
p16 = (u8_t *) sa_malloc (1000);
DumpMemChain ();
sa_free (p1);
sa_free (p16);
sa_free (p2);
sa_free (p15);
sa_free (p6);
sa_free (p14);
sa_free (p7);
sa_free (p13);
sa_free (p8);
sa_free (p12);
sa_free (p9);
sa_free (p11);
sa_free (p10);
sa_meminfo (&mi);
#endif
}



Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru