C语言内存管理课件_第1页
C语言内存管理课件_第2页
C语言内存管理课件_第3页
C语言内存管理课件_第4页
C语言内存管理课件_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言内存管理精品课件欢迎来到C语言内存管理精品课件!本课程将带你深入了解C语言内存管理的奥秘,帮助你成为一名精通内存管理的C语言编程高手!课程目标:理解内存管理的重要性高效编程掌握内存管理技巧,提高代码效率,避免资源浪费。稳定性正确管理内存,减少内存泄漏和段错误等问题,提高程序稳定性。安全学习内存安全知识,防止恶意攻击,保障程序安全。C语言内存管理概述1内存管理是程序运行时分配、管理和释放内存空间的过程。2C语言提供了一系列内存管理函数,开发者需要手动管理内存。3正确的内存管理是编写高质量C程序的关键。为什么需要内存管理?有限资源计算机内存资源有限,需要合理分配才能保证程序顺利运行。数据持久化内存管理允许程序在运行时动态分配和释放内存,存储和处理数据。高效利用合理管理内存可以避免资源浪费,提高程序性能。内存泄漏的危害内存泄漏是指程序动态分配的内存空间在使用完毕后没有及时释放,导致内存资源被占用无法释放,最终可能导致程序崩溃。内存泄漏会占用系统资源,导致程序运行速度变慢,甚至无法正常工作。内存泄漏会导致程序难以调试和维护,增加了开发成本。动态内存分配的优势灵活可以根据需要分配任意大小的内存空间,适应程序运行时的需求。1高效只有在需要时才分配内存,避免了资源浪费。2可扩展动态内存分配允许程序在运行时根据需要扩展内存空间,提高程序的扩展性。3静态内存分配vs动态内存分配静态内存分配在编译阶段分配内存,内存大小固定,在程序运行期间无法改变。动态内存分配在程序运行时分配内存,可以根据需要分配和释放内存空间,内存大小可变。静态内存:定义及特点1编译阶段分配在编译阶段分配内存,内存大小固定。2生命周期程序运行期间一直存在,直到程序结束才释放内存。3效率由于在编译阶段分配内存,静态内存分配速度快。动态内存:定义及特点运行时分配在程序运行时分配内存,内存大小可以根据需要改变。生命周期程序员需要手动释放分配的内存空间,否则会导致内存泄漏。灵活动态内存分配可以满足程序运行时不断变化的内存需求。C语言中的内存区域划分代码段存储程序代码,在程序运行期间不可修改。数据段存储程序中全局变量和静态变量。BSS段存储未初始化的全局变量和静态变量,默认值为0。堆用于动态内存分配,由程序员控制分配和释放。栈用于存储局部变量、函数参数和返回值,由系统自动管理。代码段(TextSegment)代码段存储程序代码,包含程序指令、函数定义和数据结构定义等信息。在程序运行期间,代码段是只读的,这意味着程序代码在运行过程中不可被修改。代码段通常位于内存的较低地址区域。数据段(DataSegment)数据段存储程序中的全局变量和静态变量。全局变量是指在函数外部定义的变量,其作用域是整个程序;静态变量是指在函数内部使用static关键字修饰的变量,其作用域是该函数内部。数据段通常位于内存的较高地址区域。BSS段(BSSSegment)BSS段存储未初始化的全局变量和静态变量。这些变量在程序启动时默认值为0,BSS段通常位于数据段的前面。BSS段的大小并不在可执行文件中,而是由操作系统在程序启动时分配的。堆(Heap)堆是程序动态分配内存的区域。程序员可以通过malloc()、calloc()、realloc()等函数在堆上分配内存。堆的内存空间由程序员管理,需要手动释放不再使用的内存空间,否则会导致内存泄漏。堆通常位于内存的较高地址区域。栈(Stack)栈是程序运行时用于存储局部变量、函数参数和返回值的区域。栈的内存空间由系统自动管理,不需要程序员手动分配和释放。栈通常位于内存的较高地址区域,遵循“后进先出”(LIFO)的原则。堆和栈的区别详解栈由系统自动管理后进先出(LIFO)存储局部变量、函数参数和返回值内存分配速度快堆由程序员手动管理可以分配任意大小的内存空间存储动态分配的内存空间内存分配速度相对较慢栈的特性和用途1栈是程序运行时的重要内存区域,存储着函数调用过程中所需的数据。2栈的空间大小通常是固定的,如果栈溢出,会导致程序崩溃。3栈的内存分配速度快,适合存储局部变量等临时数据。堆的特性和用途1堆是程序员用来存储动态分配内存的区域,可以根据需要分配和释放内存空间。2堆的空间大小通常是可变的,但需要程序员手动释放不再使用的内存空间,否则会导致内存泄漏。3堆的内存分配速度相对较慢,适合存储需要长期保存的数据。malloc()函数:动态分配内存malloc()函数是C语言中动态分配内存的标准库函数。它从堆上分配指定大小的内存块,并返回指向该内存块第一个字节的指针。如果分配失败,则返回NULL指针。malloc()函数的使用方法malloc()函数的语法如下:```cvoid*malloc(size_tsize);```参数size是要分配的内存块的大小,单位是字节。malloc()函数返回指向分配内存块的第一个字节的指针。如果分配失败,则返回NULL指针。例如:```cint*ptr=(int*)malloc(sizeof(int)*10);```这行代码将在堆上分配10个整数大小的内存空间,并将指向该内存块的指针存储在ptr指针中。malloc()的返回值和错误处理malloc()函数的返回值是一个指向分配内存块的指针。如果分配失败,则返回NULL指针。因此,在使用malloc()函数分配内存后,一定要检查返回值是否为NULL。如果返回值为NULL,则表示内存分配失败,程序应该进行相应的处理,例如:```cint*ptr=(int*)malloc(sizeof(int)*10);if(ptr==NULL){//内存分配失败,进行错误处理printf("Memoryallocationfailed\n");exit(1);}```这行代码将检查malloc()函数的返回值是否为NULL。如果返回值为NULL,则打印错误信息并退出程序。calloc()函数:初始化内存calloc()函数是C语言中动态分配内存并初始化为0的标准库函数。它从堆上分配指定数量的内存块,并将内存空间初始化为0。如果分配失败,则返回NULL指针。calloc()函数的使用方法calloc()函数的语法如下:```cvoid*calloc(size_tnum,size_tsize);```参数num是要分配的内存块的数量,参数size是每个内存块的大小,单位是字节。calloc()函数返回指向分配内存块的第一个字节的指针。如果分配失败,则返回NULL指针。例如:```cint*ptr=(int*)calloc(10,sizeof(int));```这行代码将在堆上分配10个整数大小的内存空间,并将内存空间初始化为0,并将指向该内存块的指针存储在ptr指针中。calloc()与malloc()的区别malloc()分配指定大小的内存空间不进行初始化内存内容可能包含垃圾数据calloc()分配指定数量的内存块,每个内存块的大小相同将分配的内存空间初始化为0内存内容被初始化为0realloc()函数:重新分配内存realloc()函数是C语言中动态调整已经分配内存块大小的标准库函数。它可以将已分配的内存块扩展或缩小。如果分配失败,则返回NULL指针。realloc()函数的使用方法realloc()函数的语法如下:```cvoid*realloc(void*ptr,size_tnew_size);```参数ptr是指向要重新分配内存块的指针,参数new_size是新的内存块大小,单位是字节。realloc()函数会尝试将ptr指向的内存块扩展或缩小到new_size大小。如果重新分配成功,则返回指向新的内存块的指针。如果重新分配失败,则返回NULL指针。例如:```cint*ptr=(int*)malloc(sizeof(int)*10);//...ptr=(int*)realloc(ptr,sizeof(int)*20);```这行代码将尝试将ptr指向的内存块扩展到20个整数大小的内存空间。如果重新分配成功,则ptr指针将指向新的内存块,否则ptr指针将指向NULL指针。realloc()的注意事项使用realloc()函数时需要注意以下几点:-如果ptr为NULL,则realloc()函数的行为等同于malloc()函数。-如果new_size为0,则realloc()函数会释放ptr指向的内存块并返回NULL指针。-如果重新分配失败,则ptr指向的内存块不会被修改,realloc()函数会返回NULL指针。-如果重新分配成功,则ptr指向的内存块可能会被移动到内存中的其他位置,因此需要更新所有指向该内存块的指针。free()函数:释放内存free()函数是C语言中动态释放内存的标准库函数。它释放由malloc()、calloc()或realloc()函数分配的内存空间。如果参数ptr为NULL,则free()函数什么也不会做。free()函数的重要性释放不再使用的内存空间非常重要。如果程序动态分配的内存空间在使用完毕后没有及时释放,会导致内存泄漏,最终可能导致程序崩溃。因此,在使用完动态分配的内存空间后,一定要及时调用free()函数将其释放。避免重复释放内存(DoubleFree)重复释放内存是指将同一个内存块释放两次或多次,会导致程序崩溃。重复释放内存通常是由编程错误引起的,例如:```cint*ptr=(int*)malloc(sizeof(int));free(ptr);free(ptr);```这行代码会将ptr指向的内存块释放两次,导致程序崩溃。内存泄漏:原因和避免方法1内存泄漏是指程序动态分配的内存空间在使用完毕后没有及时释放,导致内存资源被占用无法释放,最终可能导致程序崩溃。2常见原因:忘记释放内存、循环分配内存、指针丢失、资源泄漏。3避免方法:使用智能指针、代码审查、使用内存泄漏检测工具等。内存泄漏的常见场景内存泄漏在实际开发中很常见,以下是一些常见的场景:-忘记释放内存:在使用完动态分配的内存空间后,忘记调用free()函数将其释放。-循环分配内存:在循环中不断分配内存,但没有释放,导致内存空间被不断占用,最终导致内存泄漏。-指针丢失:在程序中使用指针指向动态分配的内存空间,但后来将指针指向了其他内存地址,导致无法访问原来的内存空间,无法释放该内存空间,造成内存泄漏。-资源泄漏:除了内存资源之外,还有其他资源也会导致泄漏,例如文件、数据库连接等。如果这些资源在使用完毕后没有及时释放,也会导致资源泄漏。使用Valgrind检测内存泄漏Valgrind是一个强大的内存泄漏检测工具,它可以帮助开发人员找出程序中潜在的内存泄漏问题。Valgrind的使用方法很简单,只需将要检测的程序作为参数传入Valgrind即可。例如:```valgrind./myprogram```Valgrind会运行程序,并检测程序运行过程中的内存泄漏问题。如果检测到内存泄漏,Valgrind会输出详细的报告,包括泄漏的内存地址、大小、调用堆栈等信息,帮助开发人员定位问题所在。调试工具:GDB的使用GDB(GNUDebugger)是一个强大的调试工具,它可以帮助开发人员调试程序,定位程序中的错误,例如内存泄漏、段错误等。GDB的使用方法很多,例如:-使用`run`命令运行程序,使用`break`命令设置断点,使用`next`命令单步执行程序,使用`print`命令查看变量的值,使用`continue`命令继续执行程序等。-GDB可以帮助开发人员查看程序运行过程中的内存状态,例如使用`x`命令查看内存地址的内容,使用`infostack`命令查看调用堆栈等,帮助开发人员定位内存泄漏问题。GDB调试内存泄漏示例以下是一个使用GDB调试内存泄漏的示例:```(gdb)run...(gdb)breakmainBreakpoint1at0x4004e8:filemain.c,line10.(gdb)continue...(gdb)pptr$1=(int*)0x10000000(gdb)x/10xw0x100000000x10000000:0x010x000x000x000x000x000x000x000x000x00(gdb)freeptr(gdb)pptr$2=(int*)0x10000000(gdb)x/10xw0x100000000x10000000:0x010x000x000x000x000x000x000x000x000x00(gdb)quit```从GDB的输出可以看出,即使在调用free()函数释放内存后,ptr指针仍然指向原来的内存地址,并且内存内容仍然没有被修改,这说明出现了内存泄漏问题。开发人员需要找到代码中释放内存的逻辑错误,并进行修复。野指针(DanglingPointer)野指针是指指向已经释放的内存空间的指针。野指针是一个非常危险的错误,因为它可能导致程序访问非法内存,从而导致程序崩溃。例如:```cint*ptr=(int*)malloc(sizeof(int));free(ptr);*ptr=10;//访问已经释放的内存空间,会导致程序崩溃```这行代码会将ptr指向的内存块释放,然后尝试将10写入该内存块,会导致程序崩溃。野指针的产生原因野指针的产生原因主要有以下几种:-释放了内存空间后,没有将指针设置为NULL。-指针指向的内存空间被释放,但指针仍然指向原来的地址。-指针指向的内存空间被另一个指针覆盖,导致指向原来的内存空间的指针成为野指针。-指针变量没有初始化,导致它指向一个未知的内存地址,成为野指针。如何避免野指针1为了避免野指针,可以采取以下措施:-在释放内存空间后,立即将指针设置为NULL,例如:```cint*ptr=(int*)malloc(sizeof(int));free(ptr);ptr=NULL;```2不要使用已经释放的内存空间,例如:```cint*ptr=(int*)malloc(sizeof(int));free(ptr);*ptr=10;//不要访问已经释放的内存空间```3在使用指针之前,先检查它是否为NULL,例如:```cint*ptr=(int*)malloc(sizeof(int));if(ptr!=NULL){*ptr=10;}```空指针(NullPointer)空指针是指指向内存地址0的指针。空指针可以用来表示不存在的地址,防止程序访问非法内存。例如:```cint*ptr=NULL;```这行代码将ptr指针设置为NULL,表示它不指向任何内存空间。如果尝试访问空指针指向的内存空间,会导致程序崩溃。空指针的用途和检查空指针主要有以下几个用途:-表示不存在的地址。-防止程序访问非法内存。-作为函数参数,表示没有数据需要处理。-检查指针是否有效。在使用指针之前,一定要先检查它是否为NULL,例如:```cint*ptr=(int*)malloc(sizeof(int));if(ptr!=NULL){*ptr=10;}```这行代码将检查ptr指针是否为NULL。如果ptr指针为NULL,则表示内存分配失败,程序应该进行相应的处理,例如退出程序。段错误(SegmentationFault)段错误是指程序试图访问非法内存区域,例如访问已经释放的内存空间、访问没有权限访问的内存空间等。段错误会导致程序崩溃。例如:```cint*ptr=NULL;*ptr=10;//访问空指针指向的内存空间,会导致段错误```这行代码会尝试将10写入空指针指向的内存空间,会导致程序崩溃。段错误的常见原因段错误的常见原因主要有以下几种:-访问空指针指向的内存空间。-访问已经释放的内存空间。-访问超出数组边界的内存空间。-访问没有权限访问的内存空间。如何调试段错误调试段错误可以使用GDB(GNUDebugger)工具。GDB可以帮助开发人员查看程序运行过程中的内存状态,例如使用`x`命令查看内存地址的内容,使用`infostack`命令查看调用堆栈等,帮助开发人员定位段错误问题。例如:```(gdb)run...(gdb)breakmainBreakpoint1at0x4004e8:filemain.c,line10.(gdb)continue...(gdb)pptr$1=(int*)0x0(gdb)x/10xw0x00x0:0x00x00x00x00x00x00x00x00x00x0(gdb)p*ptr...ProgramreceivedsignalSIGSEGV,Segmentationfault.0x00000000004004eainmain(argc=1,argv=0x7fffffffe348)atmain.c:1010*ptr=10;(gdb)quit```从GDB的输出可以看出,程序在执行`*ptr=10;`这行代码时发生了段错误。因为ptr指针的值为NULL,它指向了内存地址0,而程序不能访问地址0,因此发生了段错误。开发人员需要找到代码中访问非法内存空间的逻辑错误,并进行修复。内存越界访问(MemoryOut-of-Bounds)内存越界访问是指程序访问了数组边界之外的内存空间。内存越界访问会导致程序崩溃,也可能会覆盖其他数据,导致程序出现不可预知的结果。例如:```cintarr[10];arr[10]=10;//访问数组边界之外的内存空间,会导致程序崩溃```这行代码会尝试将10写入数组arr的第11个元素,因为arr数组只有10个元素,所以这会导致程序崩溃。读越界和写越界读越界程序试图读取数组边界之外的内存空间,可能会导致程序崩溃或读取到错误的数据。写越界程序试图写入数组边界之外的内存空间,可能会导致程序崩溃或覆盖其他数据,导致程序出现不可预知的结果。内存对齐(MemoryAlignment)内存对齐是指将数据存储在内存中的特定地址上,以提高内存访问速度。内存对齐可以提高程序的性能,但也需要程序员注意一些规则,避免内存访问错误。为什么需要内存对齐内存对齐可以提高内存访问速度的原因主要有以下几点:-现代计算机的CPU采用的是缓存机制,缓存可以加速内存访问。当数据按照特定对齐方式存储时,CPU可以更快地访问缓存中的数据,从而提高程序性能。-一些硬件设备可能要求数据按照特定对齐方式存储,否则可能会导致访问错误。-内存对齐可以减少内存碎片,提高内存利用率。-为了方便程序员管理内存,很多编译器会默认对数据进行内存对齐。-为了提高程序的可移植性,一些平台可能会对数据进行内存对齐,例如一些嵌入式平台。内存对齐的规则内存对齐规则主要取决于数据的类型和平台的架构。以下是一些通用的内存对齐规则:-数据类型的大小:数据类型的大小是决定内存对齐方式的重要因素。例如,int类型的数据通常需要4字节对齐,double类型的数据通常需要8字节对齐。-平台的架构:不同的平台架构可能会有不同的内存对齐规则。例如,x86平台通常采用4字节对齐,而ARM平台可能采用8字节对齐。-编译器的设置:编译器可以设置内存对齐方式,例如可以使用`#pragmapack`指令来调整内存对齐方式。-结构体的内存对齐:结构体中的成员变量也会按照一定的规则进行对齐。结构体的大小通常会比成员变量总大小大,这是因为结构体中可能会加入一些填充字节,以满足内存对齐的要求。-数组的内存对齐:数组中的元素也会按照一定的规则进行对齐。数组的大小通常会比元素大小的乘积大,这是因为数组中可能会加入一些填充字节,以满足内存对齐的要求。内存池(MemoryPool)内存池是一种预先分配一定大小的内存空间,然后将这些内存空间划分为固定大小的块,供程序使用。当程序需要分配内存时,从内存池中获取一个空闲的内存块。当程序释放内存时,将内存块归还到内存池中。内存池可以提高内存分配和释放的效率,减少内存碎片,降低程序的内存消耗。内存池的设计思路内存池的设计思路主要包括以下几个步骤:-预先分配内存:在程序启动时,预先分配一定大小的内存空间,作为内存池。-分块管理:将内存池划分为固定大小的内存块,每个内存块的大小可以根据程序的需要进行设置。-管理空闲块:维护一个空闲块列表,用来记录内存池中空闲的内存块。-分配内存:当程序需要分配内存时,从空闲块列表中获取一个空闲的内存块,并将该内存块分配给程序。-释放内存:当程序释放内存时,将释放的内存块归还到空闲块列表中。-扩展内存池:如果内存池中的空闲块不足,则可以扩展内存池,分配更多的内存空间。内存池的优势和适用场景优势提高内存分配和释放的效率减少内存碎片降低程序的内存消耗简化内存管理适用场景频繁分配和释放内存的场景,例如游戏引擎、数据库系统等需要严格控制内存消耗的场景,例如嵌入式系统、实时系统等需要提高程序性能的场景,例如高性能计算、并行计算等智能指针(SmartPointers)智能指针是一种特殊的指针,它可以自动管理内存,避免内存泄漏和野指针问题。智能指针通常采用RAII(ResourceAcquisitionIsInitialization)技术,即在构造函数中分配内存,在析构函数中释放内存。当智能指针对象超出作用域时,它的析构函数会被自动调用,从而释放内存。智能指针的原理智能指针的实现原理主要包括以下几个步骤:-管理原始指针:智能指针内部包含一个原始指针,用来指向动态分配的内存空间。-重载运算符:重载运算符,例如`*`、`->`等,方便程序员像使用普通指针一样使用智能指针。-析构函数:在智能指针对象超出作用域时,它的析构函数会被自动调用,释放原始指针指向的内存空间。-其他功能:一些智能指针还提供了一些额外的功能,例如引用计数、线程安全等。C++中的智能指针应用C++中提供了三种主要的智能指针:-`unique_ptr`:独占式指针,只能有一个`unique_ptr`对象指向同一个内存块,在超出作用域时自动释放内存。-`shared_ptr`:共享式指针,可以有多个`shared_ptr`对象指向同一个内存块,使用引用计数来管理内存,在最后一个指向内存块的`shared_ptr`对象超出作用域时自动释放内存。-`weak_ptr`:弱引用指针,用于辅助`shared_ptr`,防止循环引用导致内存泄漏,它不拥有内存,不影响内存的释放,但可以检查`shared_ptr`指向的对象是否已经被释放。内存管理最佳实践1始终检查malloc()、calloc()和realloc()的返回值,确保内存分配成功。2在使用完动态分配的内存空间后,立即调用free()函数将其释放,避免内存泄漏。3避免重复释放内存,确保每个内存块只释放一次。4使用智能指针,简化内存管理,避免内存泄漏和野指针问题。5使用内存泄漏检测工具,例如Valgrind,帮助找出程序中的内存泄漏问题。6使用调试工具,例如GDB,帮助调试程序,定位程序中的内存错误。7编写清晰易懂的代码,使用适当的注释,方便其他开发人员理解代码逻辑。8定期进行代码审查,检查代码中是否存在内存管理错误。代码审查中的内存管理代码审查是发现和修复代码中潜在错误的重要环节,在代码审查中,重点关注以下内存管理方面的错误:-内存泄漏:确保每个动态分配的内存块在使用完毕后都及时释放,避免内存泄漏。-野指针:确保每个指针指向有效的内存空间,避免野指针问题。-内存越界访问:确保每个指针指向的内存空间都在数组边界内,避免内存越界访问。-数组大小:确保数组的大小足够容纳所有元素,避免数组越界访问。-指针初始化:确保每个指针在使用之前都进行了初始化,避免指向未知内存空间。-指针类型:确保指针类型与指向的内存空间类型一致,避免类型转换错误。编写清晰易懂的注释清晰易懂的注释是代码维护的关键。注释可以帮助其他开发人员理解代码逻辑,快速定位错误。在代码中,应该针对内存管理相关代码进行清晰的注释,例如:-对动态分配的内存空间进行注释,说明其用途、大小等信息。-对指针变量进行注释,说明其指向的内存空间类型、用途等信息。-对内存释放操作进行注释,说明释放的内存空间是哪个动态分配的内存空间。-对可能出现内存错误的代码进行注释,说明可能导致的错误类型、如何避免等信息。实际案例分析:内存管理错误以下是一个实际案例,分析代码中的内存管理错误:```c#include#includeintmain(){int*ptr=(int*)malloc(sizeof(int));*ptr=10;//...return0;}```这行代码存在一个潜在的内存泄漏问题。在程序结束时,没有释放ptr指向的内存空间,会导致内存泄漏。为了解决这个问题,应该在程序结束之前释放ptr指向的内存空间,例如:```c#include#includeintmain(){int*ptr=(int*)malloc(sizeof(int));*ptr=10;//...free(ptr);//释放ptr指向的内存空间return0;}```分析代码中的内存泄漏使用Valgrind等工具可以分析代码中的内存泄漏问题。Valgrind会在程序运行过程中检测内存泄漏问题,并输出详细的报告,帮助开发人员定位问题所在。例如:```==1337==Memcheck,amemoryerrordetector==1337==Copyright(C)2002-2017,andGNUGPL'd,JulianSewardetal.==1337==UsingValgrind-3.13.0andLibVEX;rerunwith-hforcopyrightinfo==1337==Command:./myprogram==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337====1337==Processterminatingwitherror(1)==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337====1337==Processterminatingwitherror(1)==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337====1337==Processterminatingwitherror(1)==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337====1337==Processterminatingwitherror(1)==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337====1337==Processterminatingwitherror(1)==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocated==1337====1337==LEAKSUMMARY:==1337==definitelylost:4tesin1blocks==1337==indirectlylost:0tesin0blocks==1337==possiblylost:0tesin0blocks==1337==stillreachable:0tesin0blocks==1337==suppressed:0tesin0blocks==1337====1337==Forcountsofdetectedandsuppressederrors,rerunwith:-v==1337==ERRORSUMMARY:1errorsfrom1contexts(suppressed:0from0)==1337====1337==1errorsdetectedintheapplication==1337==atexit:1leakfor4tesin1blocks.==1337====1337====1337==Processterminatingwitherror(1)==1337====1337==HEAPSUMMARY:==1337==inuseatexit:4tesin1blocks==1337==totalheapusage:1allocs,0frees,4tesallocate

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论