200910

来源:互联网 发布:数空车床编程视频教程 编辑:程序博客网 时间:2024/06/06 07:24

1     题目概述:采用动态单向链表实现内存监控功能

1.1     试题简介

使用动态单链表的方式,不考虑多线程,编写MLC(Memory Leak Check)程序,监控应用程序的内存申请释放动作。

请考生仔细阅读以下几个章节,注意题目要求和工程、工具的介绍。

答卷提交如果采用VC调测环境(推荐使用VC环境),则把工程中的mlc目录(包括完成的源码跟测试代码)打包;如果采用Tornado调测环境(可以使用,需要考生参考试题中的用例进行测试),则把源文件mlc_main.c和mlc_main.h打包。打包文件的命名格式为“考试级别数字+调测环境代号+姓名的第一个字母+8位工号”的格式”,例如:

如李四的工号为00198765,考1级,使用VC调测环境(代号为VC),则打包文件的名称为:

1VC l00198765.rar

再如张三的工号为00187658,考0级,使用Tornado调测环境(代号为TO),则打包文件的名称为:0TO z00187658.rar

1.2     试题说明

注:本次考试提供统一的可编译可运行的调测平台,考生只需事前安装相应的开发工具即可。考试中如果考生选用VC调测(推荐使用),则直接使用提供的工程即可,Visual C++ 6.0安装会在考前知会到各个级别考生,开发环境:Visual C++ 6.0 ,测试环境:CPPUNIT;如果使用Tornado进行调测,则可参考试题中提供的“CExampleTest(测试参考).c”文件思路进行测试。

不考虑多线程,使用动态单链表的方式进行操作:在应用程序申请内存时,需要把该内存节点的信息插入链表进行记录;在应用程序释放内存时,把相应内存节点的信息从链表中删除;在应用程序退出时,如果链表中仍然存在节点,说明应用程序存在内存泄漏。应用程序不存在内存泄漏,则链表应该为空。

 

 

 

 

 

 

 

 

 


1.3     试题详细要求

1、MLC编程要求(一)

MLC程序需要完成以下标准接口,提供的框架中的源码是为了程序测试而进行的简单实现,请大家完成完备的功能(相关的类型定义会在考题提供的头文件中提供):

/*内存分配函数*/

void *MLC_MemAlloc(VOS_UINT32 ulPidSid, VOS_UINT8 ucPtNo, VOS_UINT32 ulSize, VOS_CHAR *pcFileName, VOS_UINT32 ulLine);

 

/*内存释放函数*/                          

VOS_VOID MLC_MemFree(VOS_UINT32 ulPidSid,  VOS_VOID *pAddr);

 

/*内存泄漏检查函数*/

VOS_UINT32 MLC_CheckIfMemLeak (VOS_UINT32 *pulAddrNum, VOS_VOID* pAddrArray[]);

 

/*自动回收泄漏的内存*/

VOS_VOID MLC_CollectMemory(VOS_VOID);

 

附参数说明

ulPidSid    申请内存的模块ID ,MLC程序进行内存申请时,请统一使用VOS_PID_SYS

ucPtNo      已经创建了的内存分区号, MLC程序进行内存申请时,请统一使用DYNAMIC_DOPRA_MEM_PT

ulSize        要申请的内存的大小

2、MLC编程要求(二)

/*内存泄漏检查函数,如果发现内存泄漏则按照下面的格式进行打印,如果没有泄漏则打印没有泄漏的提示信息*/

VOS_UINT32 MLC_CheckIfMemLeak (VOS_UINT32 *pulAddrNum, VOS_VOID* pAddrArray[]);

 

打印格式要求如下(示例)

Memory Leak Found:

No.  FileName         Line    MemAddr      MemSize  

1   comm_test.c       63    0x12345678      100     

2   test1.c           10    0x11223377      20

 

说明:

输出参数:

ulAddrNum为泄漏的内存块数目

pAddrArray为存储泄漏的内存块地址的buff,系统提供的默认buff大小为2048,大家可以根据自己测试需要修改CExampleTest.cpp中如下变量中的2048为所需要的大小

VOS_VOID*  g_pAddrArray[2048] = { 0 }; /*定义存放泄漏的内存块地址的buff*/

返回值    VOS_OK没有泄漏/VOS_ERR存在泄漏

FileName,文件名,文件路径无需打印。

3、MLC编程要求(三)

系统框架包括一个.h一个.c

mlc_main.h   定义对外提供的标准接口

mlc_main.c   完成程序功能的源代码,考生的代码均应放在此文件中。

 

大家需要完成下图中的“MLC程序”,图中的“应用程序”是单独提供给大家的测试框架(直接集成在试题中的VC工程中),用来对完成的程序进行自测试,测试的粒度请大家根据进度做相应安排。如果采用Tornado调测环境,则可参考试题中提供的“CExampleTest(测试参考).c”文件思路进行测试。

 

 

 

 

 

 

 

 

 


应用程序使用MLC程序提供的标准对外接口进行内存操作,并且测试检查以及回收等功能,所以标准对外接口必须按照系统定义的提供,不允许修改。

 

1.4     代码的验收用例参考(提供部分用例,参见CExampleTest.cpp文件)

注:此处只提供基本的验收用例,考生应针对题目操作和底层软件开发常识考虑各种应用的异常情况。VC调测环境可以直接使用,如果使用Tornado调测环境,则考生可通过分析如下的测试代码了解基本测试用例的要求。

#include "mlc_main.h“

// 定义测试用的PID

#define PID_TEST_MLC 110

VOS_VOID* g_paMemLeakAddrArray[2048] = { 0 }; /*定义存放泄漏的内存块地址的buff*/

 

// 注册测试套到CppUnit

CPPUNIT_TEST_SUITE_REGISTRATION( ExampleTest );

 

测试用例(一)

用例1:申请释放正常用例检测,无内存泄漏上报。

// 测试用例实现示例

void ExampleTest::TestCase01()

{

    VOS_UINT32 ulSize = 10;

    VOS_UINT32 ulMemLeakNum = 0;

    VOS_VOID*  pAddr  = VOS_NULL_PTR;

    // 初始化Buf

    VOS_MemSet(g_paMemLeakAddrArray, 0, sizeof(g_paMemLeakAddrArray));

   

    // 申请内存

    pAddr = MLC_MemAlloc(PID_TEST_MLC, DYNAMIC_MEM_PT, ulSize, __FILE__, __LINE__);

    if (VOS_NULL_PTR != pAddr)

    {

        // 释放内存

        MLC_MemFree(PID_TEST_MLC, pAddr);

    }

    // 检查结果

    CPPUNIT_ASSERT(VOS_OK == MLC_CheckIfMemLeak(&ulMemLeakNum, g_paMemLeakAddrArray));

    CPPUNIT_ASSERT(0 == ulMemLeakNum);

}

 

测试用例(二)

 

//用例2:泄漏1块内存,进行自动回收

void ExampleTest::TestCase02()

{

    VOS_UINT32 ulSize = 10;

    VOS_VOID*  pAddr  = VOS_NULL_PTR;

    VOS_UINT32 ulMemLeakNum = 0;

    VOS_VOID*  pAddrArray[2048] = { 0 };

 

    // 初始化Buf

    VOS_MemSet(g_paMemLeakAddrArray, 0, sizeof(g_paMemLeakAddrArray));

   

    // 申请内存

    pAddr = MLC_MemAlloc(PID_TEST_MLC, DYNAMIC_MEM_PT, ulSize, __FILE__, __LINE__);

    pAddrArray[0] = pAddr;

   

    // 检查结果,因为MLC_CheckIfMemLeak是打桩的,故不通过,大家完成MLC_CheckIfMemLeak后应该为测试通过

    CPPUNIT_ASSERT(VOS_ERR == MLC_CheckIfMemLeak(&ulMemLeakNum, g_paMemLeakAddrArray));

    CPPUNIT_ASSERT(pAddrArray[0] ==  g_paMemLeakAddrArray [0]);

    CPPUNIT_ASSERT(1 == ulMemLeakNum);

 

    //回收泄漏的内存

    MLC_CollectMemory();

 

    // 检查结果

    CPPUNIT_ASSERT(VOS_OK == MLC_CheckIfMemLeak(&ulMemLeakNum, g_paMemLeakAddrArray));

}

 

测试用例(三)

//用例3:泄漏多块内存,进行自动回收

// 一级考生自行添加测试用例实现

// void ExampleTest::TestCase03()

// {

//     

// }

 

测试用例(四)

//用例4:释放一段没有申请的内存,应返回不能释放,链表没有变化;

// 一级考生自行添加测试用例实现

// void ExampleTest::TestCase04()

// {

//     

// }

 

大家可以根据需要自行添加用例进行测试,在CExampleTest.cpp中增加用例函数,在CExampleTest.h中增加新增用例的申明

 

1.5     代码的验收标准

(1)       技能鉴定小组设计测试用例进行测试,不同用例分值可能不同;

(2)       0级满分:通过已提供12所有测试用例,且在规定时间内提交;

(3)       1级满分:除通过已提供12所有测试用例,还需考生自行思考其他测试用例,且在规定时间内提交;

1.6     系统库函数原型介绍

【一】使用VC调测环境

包含“vos.h”即可使用系统提供的库函数

内存申请

VOS_VOID *VOS_MemAlloc( VOS_UINT32 ulPidSid, VOS_UINT8 ucPtNo, VOS_UINT32ulSize );

参数说明:

ulPidSid    申请内存的模块ID ,MLC程序进行内存申请时,请统一使用VOS_PID_SYS

ucPtNo      已经创建了的内存分区号, MLC程序进行内存申请时,请统一使用DYNAMIC_DOPRA_MEM_PT

ulSize        要申请的内存的大小

 

内存释放

VOS_UINT32 VOS_MemFree( VOS_UINT32 ulPidSid, void *pAddr );

参数说明:

ulPidSid   申请内存的模块ID

pAddr      所要释放的内存块的首地址

 

打印函数:

VOS_INT32 vos_printf( VOS_CHAR *pscformat, ... );

Example:

vos_printf("%c\t%s\r\n",cVal,acVal);

 

【二】使用Tornado调测环境

内存申请

void *malloc

    (

    size_t nBytes             /* number of bytes to allocate */

    )

 

void *memalign

    (

    unsigned alignment,       /* boundary to align to (power of 2) */

    unsigned size             /* number of bytes to allocate */

    )

 

内存释放

void free

    (

    void * ptr                /* pointer to block of memory to free */

    )

 

打印函数:

int printf

    (

    const char * fmt,         /* format string to write */

                 ...          /* optional arguments to format string */

    )

Example:

printf(“[EXAM] Hello World \n”);

 

 

【三】MLC程序模板(以VC工程为例,具体参考试题提供的源文件)

#include "vos.h"

#include “mlc_main.h“

 

VOS_VOID *MLC_MemAlloc (VOS_UINT32 ulPidSid, VOS_UINT8 ucPtNo, VOS_UINT32 ulSize,  VOS_CHAR *pcFileName, VOS_UINT32 ulLine)

{

       /*在这里完成功能*/

}

 

VOS_VOID MLC_MemFree (VOS_UINT32 ulPidSid, VOS_VOID *pAddr)

{

      /*在这里完成功能*/

}

 

VOS_UINT32 MLC_CheckIfMemLeak (VOS_UINT32 *pulAddrNum, VOS_VOID* pAddrArray[])

{

     /*在这里完成功能*/

}

返回值    VOS_OK没有泄漏/VOS_ERR存在泄漏

 

VOS_VOID MLC_CollectMemory(VOS_VOID)

{

      /*在这里完成功能*/

}

1.7 mlc_workspace工程介绍

cppunit:

测试框架,主要包含了cppunit的头文件以及库文件;

 

dopra:

编程平台,包含了基本头文件、库文件;

工程路径:

..\mlc_workspace\mlc_workspace\mlc_workspace\dopra\target\project\win32

点击Dopra.dsw直接运行

 

mlc:

源代码以及测试代码目录,大家需要完成的文件全部存储到此目录下;

 

pc-lint:

代码静态检查,大家直接执行下面的lint.bat即可对代码进行检查;

1.8     附录:应用程序测试运行示例以及相关注意事项(VC调测环境)

【一】在VC环境下编译运行后,出现如下运行结果:

图示为Demo2个用例的执行结果,用例2因为函数功能没有完成而执行失败,

大家完成完备的函数功能后,用例应该为执行通过。

 

 

 

 

 

 

 

 

 

 

 

 

 


Runs:执行的总用例数

Failures:失败的用例数,这里指断言不成立

Errors:程序异常,比如空指针,除0操作等异常

 

【二】友情提醒

请注意随时保存结果,以避免意外损失

 

 

原创粉丝点击