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语言提供了一些内存管理函数,如malloc、calloc和realloc,用于动态分配内存空间。
这些函数可以根据需要分配指定大小的内存,并返回一个指向该内存的指针。
使用完毕后,可以通过调用free函数来释放这些内存空间,以便其他部分可以重新利用。
动态内存分配的好处是节省内存资源,但是需要开发人员自己负责内存的管理,否则容易出现内存泄漏等问题。
二、内存泄漏和内存溢出内存泄漏是指在程序运行时分配了内存空间,但在不再使用时未能及时释放,导致这部分内存无法再次被利用。
内存泄漏会导致程序占用过多的内存资源,从而降低系统的性能和稳定性。
内存溢出则是指程序在申请内存空间时,超出了系统或进程所能提供的最大内存限制。
当程序试图分配超过系统或进程限制的内存时,会导致内存溢出。
内存溢出可能导致程序崩溃或产生未定义的行为。
为了避免内存泄漏和内存溢出的问题,开发人员需要注意以下几点:1. 动态内存分配后,必须在使用完毕后及时调用free函数释放内存。
2. 在循环中进行动态内存分配时,需要确保每次循环都释放之前分配的内存,以避免内存泄漏。
c语言malloc函数

c语言malloc函数
malloc函数:
【介绍】
malloc函数是一种C语言标准库函数,全称为memory allocation,即内存分配,是一种不改变内存中已有存储数据、即在程序执行期间申请内存空间的方法。
它为程序提供动态临时存储。
【原型】
void *malloc(size_t size);
【参数】
size:指定申请空间的大小(单位:字节byte)
【返回值】
若申请成功,则返回新分配的指针;否则,返回空指针NULL。
【应用】
1、实现动态内存的分配:malloc用于动态申请内存空间,尤其适用在现在或将来未知的变量空间大小;
2、实现复杂的结构体的存储:如果内存大小有变化的话,malloc可以根据需要重新分配内存来实现复杂的结构体的存储;
3、实现对位对大小的空间的分配:malloc函数可以连续分配满足申请
需求的内存块,可以根据实际需求实现对大小的设置;
4、实现指向函数指针的存储:malloc能够为指向函数的指针申请空间,从而更好地支持C中的函数指针技术;
5、实现对不明确大小的数组存储:malloc函数还可以应用于不明确元
素个数的数组存储,动态调整存储空间大小,可以实现动态数组;
6、实现多维数组的存储:malloc函数可以实现多维数组的存储,函数
会将一块指定大小的空间进行切分,以便实现多维数组的存储。
【说明】
malloc函数将一块连续地址的内存空间分配给程序使用,因此,在使
用malloc函数申请内存的时候,申请的空间的大小受到操作系统当前
的内存剩余量的影响。
C语言中多维数组的内存分配和释放(malloc与free)

C语言中多维数组的内存分配和释放(malloc与free)的方法
写代码的时候会碰到多维数组的内存分配和释放问题,在分配和释放过程中很容易出现错误。
下面贴上一些示例代码,以供参考。
如果要给二维数组(m*n)分配空间,代码可以写成下面:
(注意红色部分)
释放应该是:
如果为三维数组(m*n*p)分配空间呢,应该是:
释放代码为逆过程,具体代码为:
三维以上的多维数组的分配和释放,原理与上面的一样。
C中如何为第二维长度固定的二维数组分配内存
在所写的代码中,有时需要为一个二维数组分配内存,该二维数组的第一维长度不定,而第二维是固定(类似arr[n][3]的数组)。
我们可以想到的是用双指针代替数组,当然可以;也可以直接对n赋值后,直接定义arr[n][3] (C99标准支持),但这里要说的是另一种方法。
这里以将点云数据读入二维数组为例,由于点云点数n不定,可以确定的是,点是三维点,可以用以下方式定义并分配内存:
double (*arr)[3] = malloc (n*3*sizeof(double));
但在VC编译环境下,将会报错——无法从“void *”转换为“double (*)*3+” ,此时应该在malloc函数之前进行类型转换,应该如何转换呢?怎样转换才能成double (*)[3]类型呢,可以进行如下转换:
double (*arr)[3] = (double ((*)[3]))malloc (n*3*sizeof(double));。
c语言动态分配的用法

c语言动态分配的用法C语言中,动态内存分配是通过使用malloc、calloc和realloc等函数来实现的。
动态分配内存可以根据程序运行时的需要来动态分配和释放内存空间,提高程序的灵活性和效率。
1. malloc函数:用于在堆(heap)中分配指定大小的内存空间。
其函数原型为void* malloc(size_t size),其中size为要分配的内存空间的大小(以字节为单位)。
例如,以下代码动态分配了一个包含5个整数的整型数组的内存空间,并将其地址赋给指针变量p:```cint* p = (int*)malloc(5 * sizeof(int));```2. calloc函数:用于在堆中分配指定数量和大小的连续内存空间,并将其初始化为零值。
其函数原型为void* calloc(size_t num,size_t size),其中num为要分配的元素个数,size为每个元素的大小。
例如,以下代码动态分配了一个包含5个整数的整型数组的内存空间,并将其地址赋给指针变量p:```cint* p = (int*)calloc(5, sizeof(int));```3. realloc函数:用于重新分配已分配内存空间的大小。
其函数原型为void* realloc(void* ptr, size_t size),其中ptr为指向已分配内存空间的指针,size为重新分配的内存空间的大小。
例如,以下代码将已分配内存空间的大小重新设置为10个整数,并将其地址赋给指针变量p:```cint* p = (int*)malloc(5 * sizeof(int));int* q = (int*)realloc(p, 10 * sizeof(int));if (q != NULL) {p = q;}```4. free函数:用于释放由malloc、calloc和realloc函数分配的内存空间。
其函数原型为void free(void* ptr),其中ptr为指向要释放的内存空间的指针。
C语言内存管理与安全性

C语言内存管理与安全性在计算机科学领域,C语言是一门被广泛使用的编程语言,因为其高效性和灵活性而受到开发者的青睐。
然而,C语言也存在一些特殊问题,尤其是与内存管理和安全性相关的问题。
本文将探讨C语言的内存管理原则、内存泄露、缓冲区溢出等安全性问题,并提供相应的解决方案。
一、内存管理原则在C语言中,内存管理是程序员应该特别关注的重要的任务之一。
以下是一些C语言内存管理的基本原则:1. 动态内存分配:C语言中,程序员可以使用malloc()和free()函数来动态分配和释放内存。
动态内存分配可以根据程序的需要进行灵活的内存管理。
2. 避免内存泄露:内存泄露是指程序在分配内存后没有释放该内存,造成内存浪费的现象。
为了避免内存泄露,程序员需要在适当的时候调用free()函数来释放已分配的内存。
3. 内存一致性:内存一致性是指程序访问的内存地址是有效且可靠的。
程序员需要遵循规定的读写内存的顺序以确保内存一致性。
4. 常量内存:C语言中,程序员可以使用const关键字来声明常量,以防止对常量内存的非法修改。
二、内存泄露内存泄露是C语言中常见的问题之一,它会导致程序占用过多的内存资源,影响程序的性能。
以下是一些常见的原因和解决方案:1. 未释放内存:程序员需要确保在不再使用动态分配的内存时,及时使用free()函数释放该内存。
同时,程序中应避免在释放内存后仍然使用这些内存空间。
2. 循环引用:当存在循环引用时,即两个或多个对象之间相互引用,而没有其他引用指向它们时,会导致内存泄露。
此时,可以使用适当的引用计数算法来解决循环引用导致的内存泄露问题。
三、缓冲区溢出缓冲区溢出是C语言中的一种常见安全性问题。
当程序写入超过缓冲区容量的数据时,会导致数据覆盖其他内存地址,从而引发安全漏洞。
以下是一些常见的原因和解决方案:1. 字符串处理:在C语言中,字符串处理时需要格外小心,使用strncpy()函数来确保不会发生缓冲区溢出。
c语言cpu分配内存的原则

c语言cpu分配内存的原则:
以下是一些关于C语言中内存分配的原则:
1.静态存储区:这部分内存是在程序编译时分配的,包括全局变量和静态变量。
这些
变量的生命周期是整个程序的执行期间。
2.栈内存:这部分内存是在程序执行期间动态分配的,主要用来存储函数调用的局部
变量和函数参数。
当函数执行结束时,这部分内存会自动释放。
3.堆内存:这是动态内存分配区域,通过malloc,calloc等函数分配。
当不再需要这部
分内存时,应使用free函数释放。
需要注意的是,如果不正确地使用这些函数(例如,试图释放同一块内存两次或者在释放内存后继续使用它),可能会导致程序崩溃或未定义的行为。
4.代码段:也称为文本段,这是用来存储程序的二进制代码的区域。
这部分内存通常
不可写,因为它是只读的,以防止程序意外地修改其指令。
5.运行时内存分配:C语言标准库提供了一些函数用于在运行时动态分配和释放内存,
如malloc()、calloc()、realloc()和free()。
这些函数允许程序员在运行时分配和释放内存,这在处理大量数据或需要根据程序运行情况动态调整数据结构大小时非常有用。
C语言内存分配问题(整理)

我查了下资料,有说分四个,有说分五个加一个程序代码区,我没查到参考的专业书籍。所 以麻烦知道的告知一下,完善一下。
2、 内存分配方式 内存分配方式有三种:
1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整 个运行期间都存在。例如全局变量,static 变量。
4、动态分配释放内存举例 用 malloc 动态分配内存后一定要判断一下分配是否成功,判断指针的值是否为 NULL。 内存分配成功后要对内存单元进行初始化。 内存分配成功且初始化后使用时别越界了。 内存使用完后要用 free(p)释放,注意,释放后,p 的值是不会变的,仍然是一个地址值, 仍然指向那块内存区,只是这块内存区的值变成垃圾了。为了防止后面继续使用这块内存, 应在 free(p)后,立即 p=NULL,这样后面如果要使用,判断 p 是否为 NULL 时就会判断出 来。
NO.2
char *GetMemory(void) {
char Байду номын сангаас[] = hello world; retrun p; } void Test(void) { char *str = NULL; str = GetMemory(); printf(str); }
问题同 NO.1
NO.3
void GetMemory(char **p, int num) {
free(str); if(str != NULL) {
strcpy(str,"world"); printf(str); } }
问题同 NO.1 我对以上问题的分析:
NO.1:程序首先申请一个 char 类型的指针 str,并把 str 指向 NULL(即 str 里存的是 NULL 的地址,*str 为 NULL 中的值为0),调用函数的过程中做了如下动作: 1、申请一个 char 类型的指针 p, 2、把 str 的内容 copy 到了 p 里(这是参数传递过程中系统所做的), 3、为 p 指针申请了 100 个空间, 4、返回 Test 函数.最后程序把字符串 hello world 拷贝到 str 指向的内存空间里.到这里错 误出现了! str 的空间始终为 NULL 而并没有实际的空间.深刻理解函数调用的第 2 步,将不难发现问 题所在!(注意:传递的参数和消除的参数) NO.2:程序首先申请一个 char 类型的指针 str,并把 str 指向 NULL.调用函数的过程中做了 如下动作: 1申请一数组 p[]并将其赋值为 hello world(数组的空间大小为 12), 2返回数组名 p 付给 str 指针(即返回了数组的首地址). 那么这样就可以打印出字符串"hello world"了么?当然是不能的! 因为在函数调用的时候漏掉了最后一步.也就是在第2步 return 数组名后,函数调用还要 进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变 量所占用的空间.所以数组空间被释放掉了,也就是说 str 所指向的内容将不确定是什么东 西. NO.3:正确答案为可以打印出 hello.但内存泄漏了! 需要用 free()函数进行释放。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在任何程序设计环境及语言中,内存管理都十分重要。
在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的。
因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题。
第1节主要介绍内存管理基本概念,重点介绍C程序中内存的分配,以及C语言编译后的可执行程序的存储结构和运行结构,同时还介绍了堆空间和栈空间的用途及区别。
第2节主要介绍C语言中内存分配及释放函数、函数的功能,以及如何调用这些函数申请/释放内存空间及其注意事项。
3.1 内存管理基本概念3.1.1C程序内存分配1.C程序结构下面列出C语言可执行程序的基本情况(Linux 2.6环境/GCC4.0)。
可以看出,此可执行程序在存储时(没有调入到内存)分为代码区(text)、数据区(data)和未初始化数据区(bss)3个部分。
(1)代码区(text segment)。
存放CPU执行的机器指令(machine instructions)。
通常,代码区是可共享的(即另外的执行程序可以调用它),因为对于频繁被执行的程序,只需要在内存中有一份代码即可。
代码区通常是只读的,使其只读的原因是防止程序意外地修改了它的指令。
另外,代码区还规划了局部变量的相关信息。
(2)全局初始化数据区/静态数据区(initialized data segment/data segment)。
该区包含了在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据(如字符串常量)。
例如,一个不在任何函数内的声明(全局数据):使得变量maxcount根据其初始值被存储到初始化数据区中。
这声明了一个静态数据,如果是在任何函数体外声明,则表示其为一个全局静态变量,如果在函数体内(局部),则表示其为一个局部静态变量。
另外,如果在函数名前加上static,则表示此函数只能在当前文件中被调用。
(3)未初始化数据区。
亦称BSS区(uninitialized data segment),存入的是全局未初始化变量。
BSS这个叫法是根据一个早期的汇编运算符而来,这个汇编运算符标志着一个块的开始。
BSS区的数据在程序开始执行之前被内核初始化为0或者空指针(NULL)。
例如一个不在任何函数内的声明:将变量sum存储到未初始化数据区。
图3-1所示为可执行代码存储时结构和运行时结构的对照图。
一个正在运行着的C编译程序占用的内存分为代码区、初始化数据区、未初始化数据区、堆区和栈区5个部分。
(1)代码区(text segment)。
代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次(每个进程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。
代码区的指令中包括操作码和要操作的对象(或对象地址引用)。
如果是立即数(即具体的数值,如5),将直接包含在代码中;如果是局部数据,将在栈区分配空间,然后引用该数据地址;如果是BSS区和数据区,在代码中同样将引用该数据地址。
(2)全局初始化数据区/静态数据区(Data Segment)。
只初始化一次。
(3)未初始化数据区(BSS)。
在运行时改变其值。
(4)栈区(stack)。
由编译器自动分配释放,存放函数的参数值、局部变量的值等。
其操作方式类似于数据结构中的栈。
每当一个函数被调用,该函数返回地址和一些关于调用的信息,比如某些寄存器的内容,被存储到栈区。
然后这个被调用的函数再为它的自动变量和临时变量在栈区上分配空间,这就是C实现函数递归调用的方法。
每执行一次递归函数调用,一个新的栈框架就会被使用,这样这个新实例栈里的变量就不会和该函数的另一个实例栈里面的变量混淆。
(5)堆区(heap)。
用于动态内存分配。
堆在内存中位于bss区和栈区之间。
一般由程序员分配和释放,若程序员不释放,程序结束时有可能由OS回收。
之所以分成这么多个区域,主要基于以下考虑:一个进程在运行过程中,代码是根据流程依次执行的,只需要访问一次,当然跳转和递归有可能使代码执行多次,而数据一般都需要访问多次,因此单独开辟空间以方便访问和节约空间。
临时数据及需要再次使用的代码在运行时放入栈区中,生命周期短。
全局数据和静态数据有可能在整个程序执行过程中都需要访问,因此单独存储管理。
堆区由用户自由分配,以便管理。
下面通过一段简单的代码来查看C程序执行时的内存分配情况。
相关数据在运行时的位置如注释所述。
2.内存分配方式在C语言中,对象可以使用静态或动态的方式分配内存空间。
静态分配:编译器在处理程序源代码时分配。
动态分配:程序在执行时调用malloc库函数申请分配。
静态内存分配是在程序执行之前进行的因而效率比较高,而动态内存分配则可以灵活的处理未知数目的。
静态与动态内存分配的主要区别如下:静态对象是有名字的变量,可以直接对其进行操作;动态对象是没有名字的变量,需要通过指针间接地对它进行操作。
静态对象的分配与释放由编译器自动处理;动态对象的分配与释放必须由程序员显式地管理,它通过malloc()和free两个函数(C++中为new和delete运算符)来完成。
以下是采用静态分配方式的例子。
此行代码指示编译器分配足够的存储区以存放一个整型值,该存储区与名字a相关联,并用数值100初始化该存储区。
以下是采用动态分配方式的例子。
此行代码分配了10个int类型的对象,然后返回对象在内存中的地址,接着这个地址被用来初始化指针对象p1,对于动态分配的内存唯一的访问方式是通过指针间接地访问,其释放方法为:3.1.2栈和堆的区别前面已经介绍过,栈是由编译器在需要时分配的,不需要时自动清除的变量存储区。
里面的变量通常是局部变量、函数参数等。
堆是由malloc()函数(C++语言为new运算符)分配的内存块,内存释放由程序员手动控制,在C语言为free 函数完成(C++中为delete)。
栈和堆的主要区别有以下几点:(1)管理方式不同。
栈编译器自动管理,无需程序员手工控制;而堆空间的申请释放工作由程序员控制,容易产生内存泄漏。
(2)空间大小不同。
栈是向低地址扩展的数据结构,是一块连续的内存区域。
这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,当申请的空间超过栈的剩余空间时,将提示溢出。
因此,用户能从栈获得的空间较小。
堆是向高地址扩展的数据结构,是不连续的内存区域。
因为系统是用链表来存储空闲内存地址的,且链表的遍历方向是由低地址向高地址。
由此可见,堆获得的空间较灵活,也较大。
栈中元素都是一一对应的,不会存在一个内存块从栈中间弹出的情况。
(3)是否产生碎片。
对于堆来讲,频繁的malloc/free(new/delete)势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低(虽然程序在退出后操作系统会对内存进行回收管理)。
对于栈来讲,则不会存在这个问题。
(4)增长方向不同。
堆的增长方向是向上的,即向着内存地址增加的方向;栈的增长方向是向下的,即向着内存地址减小的方向。
(5)分配方式不同。
堆都是程序中由malloc()函数动态申请分配并由free()函数释放的;栈的分配和释放是由编译器完成的,栈的动态分配由alloca()函数完成,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行申请和释放的,无需手工实现。
(6)分配效率不同。
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行。
堆则是C函数库提供的,它的机制很复杂,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大的空间,如果没有足够大的空间(可能是由于内存碎片太多),就有需要操作系统来重新整理内存空间,这样就有机会分到足够大小的内存,然后返回。
显然,堆的效率比栈要低得多。
3.1.3Linux数据类型大小在Linux操作系统下使用GCC进行编程,目前一般的处理器为32位字宽,下面是/usr/include/limit.h文件对Linux下数据类型的限制及存储字节大小的说明。
1.char数据类型char类型数据所占内存空间为8位。
其中有符号字符型变量取值范围为?128~127,无符号型字符变量取值范围为0~255。
其限制如下:2.short int数据类型short int类型数据所占内存空间为16位。
其中有符号短整型变量取值范围为?32768~32767,无符号短整型变量取值范围为0~65535。
其限制如下:3.int数据类型int类型数据所占内存空间为32位。
其中有符号整型变量取值范围为?2147483648~2147483647,无符号型整型变量取值范围为0~4294967295U。
其限制如下:4.long int数据类型随着宏__WORDSIZE值的改变,long int数据类型的大小也会发生改变。
如果__WORDSIZE的值为32,则long int和int类型一样,占有32位。
在Linux GCC4.0-i386版本中,默认情况下__WORDSIZE的值为32。
其定义如下:在64位机器上,如果__WORDSIZE的值为64,long int类型数据所占内存空间为64位。
其中有长整型变量取值范围为-9223372036854775808L~3372036854775807L,无符号长整型变量取值范围为0~18446744073709551615UL。
其限制如下:5.long long int数据类型在C99中,还定义了long long int数据类型。
其数据类型限制如下:3.1.4数据存储区域实例此程序显示了数据存储区域实例,在此程序中,使用了etext、edata和end3个外部全局变量,这是与用户进程相关的虚拟地址。
在程序源代码中列出了各数据的存储位置,同时在程序运行时显示了各数据的运行位置,图3-2所示为程序运行过程中各变量的存储位置。
主函数源代码如下:子函数源代码如下:函数运行结果如下:如果运行环境不一样,运行程序的地址与此将有差异,但是,各区域之间的相对关系不会发生变化。
可以通过readelf 命令来查看可执行文件的详细内容。
3.2 内存管理函数3.2.1malloc/free函数Malloc()函数用来在堆中申请内存空间,free()函数释放原先申请的内存空间。
Malloc()函数是在内存的动态存储区中分配一个长度为size字节的连续空间。
其参数是一个无符号整型数,返回一个指向所分配的连续存储域的起始地址的指针。
当函数未能成功分配存储空间时(如内存不足)则返回一个NULL指针。
由于内存区域总是有限的,不能无限制地分配下去,而且程序应尽量节省资源,所以当分配的内存区域不用时,则要释放它,以便其他的变量或程序使用。
这两个函数的库头文件为:函数定义如下:例如:malloc()函数返回值赋给p1,又把p1的值赋给p2,所以此时p1,p2都可作为free函数的参数。