| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 13691 人关注过本帖
标题:[求助]关于free函数
只看楼主 加入收藏
baidu
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:3811
专家分:0
注 册:2005-11-4
收藏
得分:0 
注意上述程序在不同编译器得到的结果可能会有所不同,但都可以证明你的错误。

偶放弃所有文章版权,偶在BCCN论坛任何贴子,可转贴,可散发,可抄袭,可复制,可被冒名顶替,可被任何人引用到任何文章中且不写出引文出处,偶分文不取。
2006-08-04 13:33
baidu
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:3811
专家分:0
注 册:2005-11-4
收藏
得分:0 

Fense的具体实现

Fense提供Fense_Malloc、Fense_Free、Fense_Realloc及Fense_Calloc等内存管理函数,功能与C语言中的malloc、free、realloc和calloc保持一致。以下是Fense_Malloc和Fense_Free及其相关函数的大致实现。Fense_Realloc和Fense_Calloc可通过Fense_Malloc来实现,过程相对比较简单,限于篇幅,本文不再赘述。

/* Fense运行时开关 */
static int st_Disabled = 0;

/* 内存分配函数 */
void * Fense_Malloc(size_t size, char *file, unsigned long line)
{
unsigned char *ptr;
struct Head *h;

/* 对链表进行互斥存取,仅在多线程系统中需要 */
FENSE_LOCK();

/* Fense的运行时开关 */
if(st_Disabled) { ptr = malloc(size); FENSE_UNLOCK(); return(ptr); }

if(!size)
{
/* 对零分配的处理 */
#ifdef WARN_ON_ZERO_MALLOC
/* … 输出警告信息 */
#endif

FENSE_UNLOCK();
return(0);
}

/* 分配内存,包括链表节点区域和前/后监测区域 */
ptr = malloc(sizeof(struct Head) +
FENSE_FRONT_SIZE + size + FENSE_END_SIZE);
if(!ptr)
{
FENSE_UNLOCK();
return(0);
}

/* 初始化链表节点,保存分配内存的信息 */
h = (struct Head *)ptr;
h->size = size;
h->file = file;
h->line = line;

/* 将此内存块插入链表st_Head */
h->next = st_Head;
h->prev = 0;
if(st_Head)
{
st_Head->prev = h;
MakeHeaderValid(st_Head);
}
st_Head = h;

/* 为本节点区域计算校验和 */
MakeHeaderValid(h);

/* 初始化已分配的内存区 */
SetFense(ptr + sizeof(struct Head),
FENSE_FRONT_VAL, FENSE_END_SIZE);
SetFense(ptr + sizeof(struct Head) + FENSE_FRONT_SIZE + size,
FENSE_END_VAL, FENSE_END_SIZE);

#ifdef FILL_ON_MALLOC
/* 填充用户内存 */
SetFense(ptr + sizeof(struct Head) + FENSE_FRONT_SIZE,
FILL_ON_MALLOC_VAL, size);
#endif

FENSE_UNLOCK();

/* 返回用户内存区域的起始位置 */
return (ptr + sizeof(struct Head) + FENSE_FRONT_SIZE);
}

/* 为指定内存块计算校验和 */
void MakeHeaderValid(struct Head *h)
{
int c, checksum, *p;
/* 先将数据成员checksum清为0 */
h->checksum = 0;
/* 计算链表节点区域值的累加和 */
for(c = 0, checksum = 0, p = (int *)h; c < sizeof(struct Head)/sizeof(int); c++)
checksum += *p++;
/* 保存累加和的负值到数据成员checksum中 */
h->checksum = -checksum;
}

/* 设置监测区域为预设值 */
void SetFense(unsigned char *ptr, unsigned char value, size_t size)
{
memset(ptr, value, size);
}

/* 内存释放函数 */
void Fense_Free(void *uptr, char *file, unsigned long line)
{
unsigned char *ptr = (unsigned char *)uptr - sizeof(struct Head) - FENSE_FRONT_SIZE;
struct Head *h = (struct Head *)ptr;

FENSE_LOCK();

if(st_Disabled) { free(uptr); FENSE_UNLOCK(); return; }

#ifdef CHECK_ALL_MEMORY_ON_FREE
/* 检查所有Fense管理下的动态内存 */
Fense_CheckAllMemory(file, line);
#endif

/* 判断本内存块是否在st_Head中 */
#ifdef VALIDATE_FREE
if(!IsOnList(h))
{ /* ... 如果不在st_Head上,提示警告信息,退出Fense_Free */ }
#endif

/* 检查当前内存块 */
if(!CheckBlock(h, file, line))
goto fail;

/* 将当前内存块从st_Head中删除 */
if(h->prev)
{
if(!CheckBlock(h->prev, file, line))
goto fail;

h->prev->next = h->next;
/* 重新计算受到影响的前一内存块的校验和 */
MakeHeaderValid(h->prev);
}
else
st_Head = h->next;

if(h->next)
{
if(!CheckBlock(h->next, file, line))
goto fail;

h->next->prev = h->prev;
/* 重新计算受到影响的后一内存块的校验和 */
MakeHeaderValid(h->next);
}

#ifdef FILL_ON_FREE
/* 填充被释放的内存区 */
SetFense(ptr, FILL_ON_FREE_VAL,
sizeof(struct Head) + FENSE_FRONT_SIZE + h->size + FENSE_END_SIZE);
#endif

/* 释放当前内存块 */
free(ptr);

FENSE_UNLOCK();
return;

fail:
/* … 输出错误信息 */
FENSE_UNLOCK();
}

/* 检查指定内存块是否在st_Head上 1 – 在0 – 不在*/
int IsOnList(struct Head *h)
{
struct Head *curr;

curr = st_Head;
while(curr)
{
if(curr == h)
return(1);

curr = curr->next;
}

return(0);
}

/* 检查指定内存块是否发生错误操作 1 – 正确 0 – 出错 */
int CheckBlock(struct Head *h, char *file, unsigned long line)
{
unsigned char *ptr = (unsigned char *)h;
int result = 1;

if(ChecksumHeader (h))
{
/* … 提示出错 */
return(0);
}

/* 检查前端越界情况 */
if(!CheckFense(ptr + sizeof(struct Head),
FENSE_FRONT_VAL, FENSE_FRONT_SIZE))
{
/* … 提示出现前越界错误 */
result = 0;
}

/*检查后端越界情况*/
if(!CheckFense(ptr + sizeof(struct Head) + FENSE_FRONT_SIZE + h->size,
FENSE_END_VAL, FENSE_END_SIZE))
{
/* … 提示出现后越界错误 */
result = 0;
}

return(result);
}

/* 检查本链表节点区域的校验和,0 – 正确, 非0 – 不正确 */
int ChecksumHeader(struct Head *h)
{
int c, checksum, *p;

for(c = 0, checksum = 0, p = (int *)h; c < sizeof(struct Head)/sizeof(int); c++)
checksum += *p++;

return(checksum);
}

/* 检查监测区域的值是否发生改变 0 - 改变 1 - 没有改变 */
int CheckFense(unsigned char *ptr, unsigned char value, size_t size)
{
while(size--)
if(*ptr++ != value)
return(0);

return(1);
}

/* 检查st_Head上的所有内存块 */
int Fense_CheckAllMemory(char *file, unsigned long line)
{
struct Head *curr = st_Head;
int count = 0;

if(st_Disabled)
return(0);

FENSE_LOCK();

while(curr)
{
if(!CheckBlock(curr, file, line))
count++;

curr = curr->next;
}

FENSE_UNLOCK();
return(count);
}


偶放弃所有文章版权,偶在BCCN论坛任何贴子,可转贴,可散发,可抄袭,可复制,可被冒名顶替,可被任何人引用到任何文章中且不写出引文出处,偶分文不取。
2006-08-04 13:36
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
之前偶了解到在申请的空间前面还有一个内存块来记录申请空间的信息,不过偶不知道还有这么一句:

free = ptr - sizeof(struct mem_control_block); //这样就把指针倒回去了;

不过仔细想想,穆扬应该理解这个原理。三个人之中就偶没了解到这点。干杯两位

谢啦,老K。

我的原则很简单:不做不喜欢的事!
2006-08-04 13:36
baidu
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:3811
专家分:0
注 册:2005-11-4
收藏
得分:0 
偶再吃点亏,贴点好东西

偶放弃所有文章版权,偶在BCCN论坛任何贴子,可转贴,可散发,可抄袭,可复制,可被冒名顶替,可被任何人引用到任何文章中且不写出引文出处,偶分文不取。
2006-08-04 13:37
天使预备役
Rank: 2
等 级:论坛游民
威 望:3
帖 子:670
专家分:10
注 册:2004-4-6
收藏
得分:0 
strlen() 是宏还是函数?他不也什么也没有告诉么?你怎么知道长度的?

差点把你忘了...
2006-08-04 13:38
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
偶现在立刻去GOOGLE一下有关这方面深一层原理。找到好的偶贴出来。

我的原则很简单:不做不喜欢的事!
2006-08-04 13:39
穆扬
Rank: 1
等 级:禁止发言
帖 子:1910
专家分:0
注 册:2006-6-1
收藏
得分:0 
提示: 作者被禁止或删除 内容自动屏蔽

2006-08-04 14:14
穆扬
Rank: 1
等 级:禁止发言
帖 子:1910
专家分:0
注 册:2006-6-1
收藏
得分:0 
提示: 作者被禁止或删除 内容自动屏蔽

2006-08-04 14:32
baidu
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:3811
专家分:0
注 册:2005-11-4
收藏
得分:0 
以下是引用穆扬在2006-8-4 14:32:13的发言:
baidu先生

我认为你有些帖子删的无理

我重复一遍
你19楼的帖子的真实含义是什么
是否是反对我所说的"信息量足够"

31楼说30楼的代码证明了我的错误
证明了我什么错误
以及如何证明的?

你没编译器,偶替你这个高人干粗活

333333333333eeeeeeeeeeeeeeeeddddddddddddddddddddddddddddddddddddddddddd
0.
333333333333eeeeeeeeeeeeeeeeddddddddddddddddddddddddddddddddddddddddddd
1.
333333333333eeeeeeeeeeeeeeeeddddddddddddddddddddddddddddddddddddddddddd
2.

Press any key to continue...

这就是运行结果!

偶放弃所有文章版权,偶在BCCN论坛任何贴子,可转贴,可散发,可抄袭,可复制,可被冒名顶替,可被任何人引用到任何文章中且不写出引文出处,偶分文不取。
2006-08-04 14:41
穆扬
Rank: 1
等 级:禁止发言
帖 子:1910
专家分:0
注 册:2006-6-1
收藏
得分:0 
提示: 作者被禁止或删除 内容自动屏蔽

2006-08-04 14:50
快速回复:[求助]关于free函数
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.012423 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved