C++内存管理详解
使用C语言技术进行内存管理的方法

使用C语言技术进行内存管理的方法使用C语言进行内存管理的方法在编程中,内存管理是一个非常重要的问题。
合理地管理内存可以提高程序的性能和效率,避免内存泄漏和内存溢出等问题。
本文将介绍一些使用C语言技术进行内存管理的方法。
1. 动态内存分配动态内存分配是C语言中常用的内存管理技术之一。
通过动态内存分配,我们可以在程序运行时根据需要动态地分配和释放内存。
C语言提供了几个函数来进行动态内存分配,如malloc、calloc和realloc。
其中,malloc函数用于分配指定大小的内存空间,calloc函数用于分配指定数量的相同大小的内存空间,并将其初始化为0,realloc函数用于重新分配已分配内存的大小。
2. 内存释放动态分配的内存在使用完毕后必须及时释放,以免造成内存泄漏。
C语言中使用free函数来释放动态分配的内存。
当不再需要使用某块内存时,应该调用free函数将其释放,以便系统可以重新利用该内存。
3. 内存回收除了手动释放内存外,C语言还提供了一种自动回收内存的机制,即垃圾回收。
垃圾回收是一种自动管理内存的技术,它会自动检测和回收不再使用的内存,避免程序员手动释放内存的繁琐工作。
C语言中并没有内置的垃圾回收机制,但可以使用第三方库或框架来实现自动内存回收。
4. 内存池内存池是一种用于管理内存的数据结构,它可以提高内存分配和释放的效率。
内存池将一块较大的内存空间划分为多个小块,每次分配和释放内存时,只需要在内存池中进行操作,而不需要频繁地向系统申请和释放内存。
内存池可以减少内存碎片和系统调用的次数,提高程序的性能。
5. 内存对齐内存对齐是一种对齐内存访问的规范,可以提高内存访问的效率。
在C语言中,结构体和数组的内存对齐是由编译器自动完成的,但对于动态分配的内存,我们需要手动进行内存对齐。
可以使用C语言的一些特性来实现内存对齐,如使用宏定义来指定对齐方式,使用特定的数据类型来保证内存对齐。
6. 内存检测工具为了帮助程序员检测和调试内存相关的问题,C语言提供了一些内存检测工具,如valgrind和GDB。
C语言内存使用详解

C语言内存使用详解C语言是一种低级语言,开发者可以直接控制内存使用。
了解C语言内存使用的机制和技巧对于编写高效、安全和可靠的程序至关重要。
本文将详细介绍C语言内存使用的知识和技术,并提供一些实用的建议。
在C语言中,内存是以字节为单位进行管理的,通常将内存分为栈和堆两种。
栈是一种自动分配和自动释放内存的数据结构。
它的特点是后进先出(LIFO),即最后分配的内存最先释放。
栈主要用于存储局部变量、函数参数和函数调用的上下文信息。
在函数调用结束后,分配给局部变量的内存会自动释放。
堆是一种动态分配内存的数据结构,程序员可以手动分配和释放内存。
堆的管理需要调用系统提供的函数,如malloc(和free(。
堆主要用于存储动态分配的数据,如数组、结构体和指针。
程序员需要手动管理堆内存,确保及时释放不再使用的内存,否则会造成内存泄漏。
为了更好地使用内存,提高程序的性能和可靠性,下面是一些C语言内存使用的技巧和注意事项:1.使用局部变量:局部变量是保存在栈上的,它们的生命周期与函数的调用关系密切相关。
局部变量不仅可以节约内存,还可以提高程序的执行效率。
2.合理分配静态变量和全局变量:静态变量和全局变量在程序执行过程中一直存在,它们的生命周期不受函数调用的影响。
过多的静态变量和全局变量会占用大量的内存,影响程序的性能。
3. 动态分配内存时要检查返回值:在调用malloc(等动态分配内存的函数时,要检查返回值是否为NULL。
如果返回值为NULL,表示没有足够的内存可用。
处理内存分配失败的情况至关重要,可以提前终止程序或采取其他恰当的措施。
4. 及时释放不再使用的内存:动态分配的内存在不再使用时要及时释放,以避免内存泄漏。
使用free(函数将内存返回给系统,以供其他程序使用。
5.防止指针错误:指针是C语言中非常重要的概念,但也容易出现指针错误,如空指针引用、越界访问等。
使用指针时要特别小心,确保指针正确地指向有效的内存区域。
c语言的内存管理机制

c语言的内存管理机制C语言的内存管理机制内存管理是计算机编程中非常重要的一个方面,它涉及到程序在运行过程中如何使用和管理计算机的内存资源。
C语言作为一种低级语言,提供了灵活且强大的内存管理机制,程序员可以直接操作内存,对程序的性能和资源利用进行优化。
在C语言中,内存是按照字节进行管理的,每个字节都有一个唯一的地址。
程序在运行时,需要申请内存来存储变量、数组、结构体等数据。
C语言提供了几种方式来进行内存管理:1. 静态内存分配:静态内存分配是在程序编译时就确定了内存分配的大小和位置。
在C语言中,全局变量和静态变量都是静态内存分配的例子。
这些变量在程序的整个生命周期中都存在,内存分配在程序加载时就完成了。
2. 栈内存分配:栈内存分配是在程序运行时动态分配的,用于存储局部变量和函数调用信息。
栈内存的分配和释放是自动进行的,当一个函数被调用时,相关的局部变量就会被分配到栈上,当函数执行完毕时,这些变量会被自动释放。
栈内存的分配和释放速度很快,但是其大小有限,不适合存储大量的数据。
3. 堆内存分配:堆内存分配是在程序运行时动态分配的,用于存储动态分配的数据结构,例如数组、链表、树等。
堆内存的分配和释放需要程序员手动进行,通过调用malloc()函数来申请内存,调用free()函数来释放内存。
堆内存的大小取决于系统的可用内存,如果分配过多的堆内存而没有及时释放,会导致内存泄漏的问题。
C语言的内存管理机制虽然灵活,但也容易出现一些问题。
其中最常见的问题是内存泄漏和野指针。
内存泄漏是指程序在运行过程中申请了内存但没有及时释放,导致系统可用内存逐渐减少,最终导致程序崩溃。
野指针是指指向已经释放的内存地址的指针,当程序试图访问这个地址时会导致不可预料的错误。
为了避免内存泄漏和野指针问题,程序员需要遵循一些内存管理的原则:1. 在使用完毕后及时释放内存:当不再需要某个变量或数据结构时,应该立即调用相应的释放内存的函数,例如free()。
C语言的内存管理

C语言的内存管理1. 引言C语言是一种非常强大的编程语言,广泛应用于系统级编程和嵌入式开发等领域。
在C语言中,内存管理是程序员必须掌握的重要技能之一。
正确地管理内存可以提高程序的性能和稳定性,避免内存泄漏和内存溢出等问题。
2. 堆和栈在C语言中,内存分为两个主要的部分:堆和栈。
栈是一种自动分配和释放内存的数据结构,用于存储局部变量和函数调用等信息。
堆是一种手动管理内存的数据结构,用于存储动态分配的数据。
2.1 栈栈是一种后进先出的数据结构,类似于一个弹簧床。
在C语言中,栈用于存储局部变量和函数调用的上下文信息。
当函数被调用时,其局部变量和返回地址等信息会被压入栈中;当函数返回时,这些信息会被弹出栈。
栈的内存分配和释放是自动进行的,程序员无需手动管理。
2.2 堆堆是一种动态分配内存的数据结构,类似于一个自由存储区。
在C语言中,通过调用malloc()和free()等函数来手动管理堆内存。
malloc()函数用于分配一块指定大小的内存空间,而free()函数用于释放已经分配的内存空间。
3. 动态内存分配在C语言中,动态内存分配是一种手动管理内存的方式,通过在堆中分配和释放内存空间来实现。
动态内存分配可以解决静态内存分配无法灵活应对变化的需求的问题。
3.1 malloc()函数在C语言中,使用malloc()函数来分配一块指定大小的内存空间。
malloc()函数的原型如下:void* malloc(size_t size);malloc()函数接受一个size_t类型的参数,表示要分配的内存空间的大小。
它返回一个void*类型的指针,指向分配的内存空间的起始地址。
如果分配失败,则返回NULL。
3.2 free()函数在C语言中,使用free()函数来释放已经分配的内存空间。
free()函数的原型如下:void free(void* ptr);free()函数接受一个void*类型的指针作为参数,指向要释放的内存空间的起始地址。
C语言内存管理与优化技巧

C语言内存管理与优化技巧Introduction:C语言是一种强大且广泛应用的编程语言,它的内存管理技巧对程序性能和资源利用至关重要。
本文将探讨C语言内存管理的基础知识,并讨论一些优化技巧,以提高程序的效率和性能。
1. 动态内存分配和释放动态内存分配允许程序在运行时动态地申请所需的内存,这对于处理变长数据以及大规模数据结构非常重要。
C语言提供了以下几个关键的函数来实现动态内存管理:1.1 malloc():用于动态分配内存,并返回指向分配内存的指针。
例如,以下代码分配了一个int类型的内存块:```cint *ptr = (int*) malloc(sizeof(int));```1.2 calloc():在动态分配内存的同时,将分配的内存区域初始化为零。
例如,以下代码分配了一个包含5个int类型元素的数组:```cint *arr = (int*) calloc(5, sizeof(int));```1.3 realloc():用于重新调整之前动态分配的内存大小。
例如,以下代码将ptr指向的内存块的大小重新调整为10:```cint *new_ptr = (int*) realloc(ptr, 10*sizeof(int));```1.4 free():用于释放动态分配的内存。
必须谨记在用完内存后及时释放,以防止内存泄漏。
例如,以下代码释放了之前分配的内存:```cfree(ptr);```2. 避免内存泄漏和内存溢出内存泄漏和内存溢出是常见的内存管理问题,会导致程序性能下降甚至崩溃。
以下是一些防止内存泄漏和内存溢出的技巧:2.1 在分配内存后确保及时释放。
例如,使用完动态分配的内存后,应当立即使用free()函数释放内存。
2.2 避免未初始化的指针。
未初始化的指针可能会指向无效的内存地址,导致程序出现不可预料的错误。
应当始终在定义指针变量时对其进行初始化。
2.3 定期检查并清理无用的动态内存。
C语言内存管理及经典算法

C语言内存管理及经典算法C语言是一种面向过程编程语言,内存管理是其重要的特性之一、C 语言中的内存管理主要包括动态内存分配、内存回收和内存泄漏等方面。
而经典算法方面,C语言广泛应用于各种数据结构和算法实现中。
下面将对C语言内存管理及经典算法进行详细介绍。
一、C语言内存管理1.动态内存分配动态内存分配是C语言的一个重要特性,通过使用malloc函数可以在程序运行时动态地分配内存。
malloc函数的原型为:```cvoid *malloc(size_t size);```其中,size参数表示需要分配的内存块的大小,函数会返回一个指向分配的内存块的指针。
需要注意的是,动态分配的内存需要手动释放,否则会导致内存泄漏。
2.内存释放内存释放是指将动态分配的内存归还给系统,避免内存泄漏。
在C语言中,使用free函数来释放动态内存:```cvoid free(void *ptr);```其中,ptr参数表示待释放的内存块的指针。
需要注意的是,只能释放动态分配的内存,不能释放栈上的内存。
3.内存泄漏内存泄漏指由于程序错误导致无法释放动态分配的内存。
内存泄漏会导致程序内存使用量超过系统限制,最终导致程序崩溃。
为避免内存泄漏,需要在每次动态分配内存后及时释放,保证程序正常运行。
二、C语言经典算法1.冒泡排序冒泡排序是一种简单且常见的排序算法,其原理是通过不断交换相邻的元素,将较大(或较小)的元素逐渐“冒泡”到数组的一端。
具体实现如下:```cvoid bubbleSort(int arr[], int n)int i, j;for (i = 0; i < n - 1; i++)for (j = 0; j < n - i - 1; j++)if (arr[j] > arr[j+1])int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}```2.快速排序快速排序是一种高效的排序算法,其思想是通过选择一个基准数,将数组分割为两个子数组,一个子数组中的所有数小于基准数,另一个子数组中的所有数大于基准数,然后递归地对两个子数组进行排序。
C语言内存使用详解

C语言内存使用详解C语言是一种底层的编程语言,对内存的使用非常重要。
本文将详细解释C语言内存的使用方法和原理。
首先,我们需要了解C语言内存的组成。
C语言内存可以分为以下几个部分:1. 栈(Stack):栈是用来存储局部变量和函数调用信息的地方。
当一个函数被调用时,它的局部变量和函数调用信息会被存储在栈中。
当函数返回时,这些数据会被自动清理。
栈是一个后进先出(LIFO)的数据结构,它的大小是固定的。
2. 堆(Heap):堆是用来存储动态分配的内存的地方。
在C语言中,我们可以使用malloc(函数来在堆上动态分配内存。
堆的大小是可变的,程序员需要手动管理内存的分配和释放。
3. 数据区(Data Segment):数据区分为全局区和静态区。
全局区用来存储全局变量和静态变量,其大小是固定的。
静态区用来存储静态局部变量,它的生命周期和程序的整个执行时间相同。
4. 代码区(Code Segment):代码区用来存储程序的执行代码,包括函数体和常量数据。
代码区是只读的,不允许进行写操作。
接下来,我们来讨论一些内存使用的注意事项。
1.局部变量和全局变量:局部变量是在函数体内定义的变量,它只在函数内部可见。
全局变量是在函数外部定义的变量,它在整个程序中可见。
局部变量存储在栈上,全局变量存储在数据区。
2. 动态内存分配:在C语言中,我们可以使用malloc(函数来在堆上动态分配内存。
动态内存分配允许我们在运行时根据需要分配内存。
使用完动态分配的内存后,我们需要手动调用free(函数来释放内存,否则会造成内存泄漏。
3.内存溢出:内存溢出指的是程序在申请内存时超出了可用的内存大小。
内存溢出可能会导致程序崩溃或者产生不可预期的行为。
为了避免内存溢出,我们应该合理地管理内存的分配和释放。
4.指针和数组:指针是用来存储内存地址的变量。
我们可以使用指针来操作内存中的数据。
数组是一种特殊的数据结构,它可以在内存中连续存储多个相同类型的数据。
C语言内存管理技巧

C语言内存管理技巧在C语言编程中,良好的内存管理是十分重要的。
合理地分配和释放内存,能够提高程序的效率和稳定性。
本文将介绍几种C语言内存管理的技巧,以帮助程序员编写更高效的代码。
一、静态内存管理静态内存是在编译时分配的内存,其生命周期贯穿整个程序的运行过程。
静态内存的使用需要谨慎,以下是几点注意事项:1. 减少全局变量的使用:全局变量存储在静态内存中,其生命周期长且占用内存空间。
因此,应尽量减少全局变量的使用,采用局部变量来替代。
2. 局部静态变量的正确使用:局部静态变量具有全局生存期,但仅在定义它们的代码块中可见。
合理使用局部静态变量可以减少对动态内存的需求。
二、动态内存管理动态内存是在程序运行期间分配和释放的内存。
C语言提供了malloc()、calloc()和realloc()等函数来实现动态内存管理。
1. 分配内存:使用malloc()函数可以在堆内存中动态分配内存。
分配的内存块大小由参数指定,返回一个指向分配内存起始地址的指针。
例如:```int* p = (int*)malloc(sizeof(int));if (p == NULL) {// 内存分配失败,进行错误处理}```2. 释放内存:使用free()函数释放之前分配的动态内存。
释放后,内存可以被重新分配给其他变量使用。
例如:```free(p);```需要注意的是,在释放内存之后,应将指针置为NULL,以避免野指针的问题。
例如:```p = NULL;```3. 内存泄漏的预防:动态内存的分配和释放必须成对出现,否则就会导致内存泄漏。
及时释放不需要的动态内存,可以避免内存泄漏问题。
三、内存对齐内存对齐是为了提高内存访问效率,通常由编译器自动完成。
在某些情况下,手动设置内存对齐方式可以提高程序的性能。
1. 结构体成员对齐:结构体中的成员在内存中的对齐方式可以手动指定,以减少内存碎片和访问延迟。
例如:```struct MyStruct {int a;char b;} __attribute__((packed));```上述代码使用了GCC编译器的特性,指定了结构体成员的紧凑对齐方式。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
经典分享 C++内存管理详解C++内存管理。
程序员们经常编写内存管理程序,往往提心吊胆。
如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的。
本文的内容比一般教科书的要深入得多,读者需细心阅读,做到真正地通晓内存管理。
1、内存分配方式内存分配方式有三种:(1)从静态存储区域分配。
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。
例如全局变量,static变量。
(2)在栈上创建。
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。
程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
2、常见的内存错误及其对策发生内存错误是件非常麻烦的事情。
编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。
而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。
有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。
常见的内存错误及其对策如下:(1)内存分配未成功,却使用了它。
编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。
常用解决办法是,在使用内存之前检查指针是否为null。
如果指针p是函数的参数,那么在函数的入口处用assert(p!=null)进行检查。
如果是用malloc或new来申请内存,应该用if(p==null) 或if(p!=null)进行防错处理。
(2)内存分配虽然成功,但是尚未初始化就引用它。
犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。
内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。
所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
(3)内存分配成功并且已经初始化,但操作越过了内存的边界。
例如在使用数组时经常发生下标“多1”或者“少1”的操作。
特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。
(4)忘记了释放内存,造成内存泄露。
含有这种错误的函数每被调用一次就丢失一块内存。
刚开始时系统的内存充足,你看不到错误。
终有一次程序突然死掉,系统出现提示:内存耗尽。
动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。
(5)释放了内存却继续使用它。
有三种情况:∙程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。
∙函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。
∙使用free或delete释放了内存后,没有将指针设置为null。
导致产生“野指针”。
【规则1】用malloc或new申请内存之后,应该立即检查指针值是否为null。
防止使用指针值为null的内存。
【规则2】不要忘记为数组和动态内存赋初值。
防止将未被初始化的内存作为右值使用。
【规则3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。
【规则4】动态内存的申请与释放必须配对,防止内存泄漏。
【规则5】用free或delete释放了内存之后,立即将指针设置为null,防止产生“野指针”。
3、指针与数组的对比c++/c程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以为两者是等价的。
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。
数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。
指针远比数组灵活,但也更危险。
下面以字符串为例比较指针与数组的特性。
3.1 修改内容示例3-1中,字符数组a的容量是6个字符,其内容为hello。
a的内容可以改变,如a[0]= ‘x’。
指针p指向常量字符串“world”(位于静态存储区,内容为world),常量字符串的内容是不可以被修改的。
从语法上看,编译器并不觉得语句p[0]= ‘x’有什么不妥,但是该语句企图修改常量字符串的内容而导致运行错误。
//示例3.1 修改数组和指针的内容char a[] = “hello”;a[0] = …x‟;cout << a << endl;char *p = “world”; // 注意p指向常量字符串p[0] = ‘x’; // 编译器不能发现该错误cout << p << endl;3.2 内容复制与比较不能对数组名进行直接复制与比较。
示例7-3-2中,若想把数组a的内容复制给数组b,不能用语句b = a ,否则将产生编译错误。
应该用标准库函数strcpy进行复制。
同理,比较b 和a的内容是否相同,不能用if(b==a) 来判断,应该用标准库函数strcmp进行比较。
语句p = a 并不能把a的内容复制指针p,而是把a的地址赋给了p。
要想复制a的内容,可以先用库函数malloc为p申请一块容量为strlen(a)+1个字符的内存,再用strcpy进行字符串复制。
同理,语句if(p==a) 比较的不是内容而是地址,应该用库函数strcmp来比较。
//示例3.2 数组和指针的内容复制与比较// 数组…char a[] = "hello";char b[10];strcpy(b, a); // 不能用b = a;if(strcmp(b, a) == 0) // 不能用if (b == a)…// 指针…int len = strlen(a);char *p = (char *)malloc(sizeof(char)*(len+1));strcpy(p,a); // 不要用p = a;if(strcmp(p, a) == 0) // 不要用if (p == a)…3.3 计算内存容量用运算符sizeof可以计算出数组的容量(字节数)。
示例7-3-3(a)中,sizeof(a)的值是12(注意别忘了’’)。
指针p指向a,但是sizeof(p)的值却是4。
这是因为sizeof(p)得到的是一个指针变量的字节数,相当于sizeof(char*),而不是p所指的内存容量。
c++/c语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
示例7-3-3(b)中,不论数组a的容量是多少,sizeof(a)始终等于sizeof(char *)。
char a[] = "hello world";char *p = a;cout<< sizeof(a) << endl; // 12字节cout<< sizeof(p) << endl; // 4字节//示例3.3(a)计算数组和指针的内存容量void func(char a[100]){cout<< sizeof(a) << endl; // 4字节而不是100字节}//示例3.3(b)数组退化为指针4、指针参数是如何传递内存的?如果函数的参数是一个指针,不要指望用该指针去申请动态内存。
示例7-4-1中,test函数的语句getmemory(str, 200)并没有使str获得期望的内存,str依旧是null,为什么?void getmemory(char *p, int num){p = (char *)malloc(sizeof(char) * num);}void test(void){char *str = null;getmemory(str, 100); // str 仍然为nullstrcpy(str, "hello"); // 运行错误}示例4.1 试图用指针参数申请动态内存毛病出在函数getmemory中。
编译器总是要为函数的每个参数制作临时副本,指针参数p 的副本是_p,编译器使_p = p。
如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。
这就是指针可以用作输出参数的原因。
在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。
所以函数getmemory并不能输出任何东西。
事实上,每执行一次getmemory就会泄露一块内存,因为没有用free释放内存。
如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例4.2。
void getmemory2(char **p, int num){*p = (char *)malloc(sizeof(char) * num);}void test2(void){char *str = null;getmemory2(&str, 100); // 注意参数是&str,而不是strstrcpy(str, "hello");cout<< str << endl;free(str);}示例4.2用指向指针的指针申请动态内存由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。
这种方法更加简单,见示例4.3。
char *getmemory3(int num){char *p = (char *)malloc(sizeof(char) * num);return p;}void test3(void){char *str = null;str = getmemory3(100);strcpy(str, "hello");cout<< str << endl;free(str);}//示例4.3 用函数返回值来传递动态内存用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。
这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例4.4。
char *getstring(void){char p[] = "hello world";return p; // 编译器将提出警告}void test4(void){char *str = null;str = getstring(); // str 的内容是垃圾cout<< str << endl;}//示例4.4return语句返回指向“栈内存”的指针用调试器逐步跟踪test4,发现执行str = getstring语句后str不再是null指针,但是str的内容不是“hello world”而是垃圾。