⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * FILE:    memory.c * AUTHORS:  Isidor Kouvelas / Colin Perkins / Mark Handley / Orion Hodson * * $Revision$ * $Date$ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions  * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by the Computer Science *      Department at University College London * 4. Neither the name of the University nor of the Department may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "config_unix.h"#include "config_win32.h"#include "debug.h"#include "memory.h"#include "util.h"#ifdef DEBUG_MEM/* Custom memory routines are here, down to #else, defaults follow */#define MAX_ADDRS         65536#define MAGIC_MEMORY      0xdeadbeef#define MAGIC_MEMORY_SIZE 4/* Allocated block format is: * <chk_header> <memory chunk...> <trailing magic number> */typedef struct {        uint32_t key;   /* Original allocation number   */        uint32_t size;  /* Size of allocation requested */        uint32_t pad;   /* Alignment padding to 8 bytes */        uint32_t magic; /* Magic number                 */} chk_header;typedef struct s_alloc_blk {        uint32_t    key;     /* Key in table (ascending) */        chk_header *addr;        char       *filen;   /* file where allocated     */        int         line;    /* line where allocated     */        size_t      length;  /* size of allocation       */        int         blen;    /* size passed to block_alloc (if relevent) */        int         est;     /* time last touched in order of all allocation and reclaims */} alloc_blk;/* Table is ordered by key */static alloc_blk mem_item[MAX_ADDRS];static int   naddr = 0; /* number of allocations */static int   tick  = 1; /* xmemchk assumes this is one, do not change without checking why */static int   init  = 0;/** * xdoneinit: * @void:  *  * Marks end of an applications initialization period.  For media * applications with real-time data transfer it's sometimes helpful to * distinguish between memory allocated during application * initialization and when application is running. **/void xdoneinit(void) {	init = tick++;}extern int chk_header_okay(const chk_header *ch);int chk_header_okay(const chk_header *ch){        const uint8_t *tm; /* tail magic */        ASSERT(ch != NULL);        if (ch->key == MAGIC_MEMORY) {                fprintf(stderr, "ERROR: freed unit being checked\n");                abort();        }        tm = (const uint8_t*)ch;        tm += sizeof(chk_header) + ch->size;        if (ch->magic != MAGIC_MEMORY) {                fprintf(stderr, "ERROR: memory underrun\n");                abort();                return FALSE;        } else if (memcmp(tm, &ch->magic, MAGIC_MEMORY_SIZE)) {                fprintf(stderr, "ERROR: memory overrun\n");                abort();                return FALSE;        }        return TRUE;}static int mem_key_cmp(const void *a, const void *b) {        const alloc_blk *g, *h;        g = (const alloc_blk*)a;        h = (const alloc_blk*)b;        if (g->key < h->key) {                return -1;        } else if (g->key > h->key) {                return +1;        }        return 0;}static alloc_blk *mem_item_find(uint32_t key) {        void      *p;        alloc_blk  t;        t.key = key;        p = bsearch((const void*)&t, mem_item, naddr, sizeof(alloc_blk), mem_key_cmp);        return (alloc_blk*)p;}/** * xmemchk: * @void:  *  * Check for bounds overruns in all memory allocated with xmalloc(), * xrealloc(), and xstrdup().  Information on corrupted blocks is * rendered on the standard error stream.  This includes where the * block was allocated, the size of the block, and the number of * allocations made since the block was created. **/void xmemchk(void){        uint32_t    last_key;        chk_header *ch;        int         i;	if (naddr > MAX_ADDRS) {		fprintf(stderr, "ERROR: Too many addresses for xmemchk()!\n");		abort();	}        last_key = 0;	for (i = 0; i < naddr; i++) {                /* Check for table corruption */                if (mem_item[i].key  < last_key) {                        fprintf(stderr, "Memory table keys out of order - fatal error");                        abort();                }                last_key = mem_item[i].key;                if (mem_item[i].addr == NULL) {                        fprintf(stderr, "Memory table entry reference null block - fatal error");                        abort();                }                if (mem_item[i].filen == NULL) {                        fprintf(stderr, "Memory table filename missing - fatal error");                        abort();                }                if ((size_t) strlen(mem_item[i].filen) != mem_item[i].length) {                        fprintf(stderr, "Memory table filename length corrupted - fatal error");                        abort();                }                                /* Check memory */                ch = mem_item[i].addr;                if (chk_header_okay(ch) == FALSE) {                        /* Chk header display which side has gone awry */			fprintf(stderr, "Memory check failed!\n");			fprintf(stderr, "addr: %p", mem_item[i].addr);                        fprintf(stderr, "  size: %6d", ch->size);                        fprintf(stderr, "  age: %6d", tick - mem_item[i].est);                        fprintf(stderr, "  file: %s", mem_item[i].filen);                        fprintf(stderr, "  line: %d", mem_item[i].line);                        fprintf(stderr, "\n");                        abort();                }        }}static int alloc_blk_cmp_origin(const void *vab1, const void *vab2){        const alloc_blk *ab1, *ab2;        int sc;                ab1 = (const alloc_blk*)vab1;        ab2 = (const alloc_blk*)vab2;        if (ab1->filen == NULL || ab2->filen == NULL) {                if (ab1->filen == NULL && ab2->filen == NULL) {                        return 0;                } else if (ab1->filen == NULL) {                        return +1;                } else /* (ab2->filen == NULL)*/ {                        return -1;                }        }        sc = strcmp(ab1->filen, ab2->filen);        if (sc == 0) {                if (ab1->line > ab2->line) {                        return +1;                } else if (ab1->line == ab2->line) {                        return 0;                } else /* (ab1->line < ab2->line) */{                        return -1;                }        }        return sc;}static intalloc_blk_cmp_est(const void *vab1, const void *vab2){        const alloc_blk *ab1, *ab2;        ab1 = (const alloc_blk*)vab1;                ab2 = (const alloc_blk*)vab2;                if (ab1->est > ab2->est) {                return +1;        } else if (ab1->est == ab2->est) {                return 0;        } else {                return -1;        }}/** * xmemdmp: * @void:  *  * Dumps the address, size, age, and point of allocation in code. * **/void xmemdmp(void){	int i;        block_release_all();	if (naddr > MAX_ADDRS) {		printf("ERROR: Too many addresses for xmemdmp()!\n");		abort();	}        qsort(mem_item, naddr, sizeof(mem_item[0]), alloc_blk_cmp_est);        for (i=0; i<naddr; i++) {                printf("%5d",i);                               fflush(stdout);                printf("  addr: %p", mem_item[i].addr);        fflush(stdout);                printf("  size: %5d", mem_item[i].addr->size); fflush(stdout);                printf("  age: %6d", tick - mem_item[i].est);  fflush(stdout);                printf("  file: %s", mem_item[i].filen);       fflush(stdout);                printf(":%d", mem_item[i].line);               fflush(stdout);                if (mem_item[i].blen != 0) {                         printf("  \tblen %d", mem_item[i].blen);                           fflush(stdout);                }                printf("\n");        }	printf("Program initialisation finished at age %6d\n", tick-init);        qsort(mem_item, naddr, sizeof(mem_item[0]), mem_key_cmp);}/* Because block_alloc recycles blocks we need to know which code * fragment takes over responsibility for the memory.  *//** * xclaim:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -