谈对C语言中内存分配的理解

来源:互联网 发布:从程序员到架构师 pdf 编辑:程序博客网 时间:2024/06/05 18:27

      在我们学习C语言的过程中,掌握内存分配是很有必要的。下面是我对内存分配的理解,如有不同的见解,请多多指教。

在C语言中,对象可以使用静态方式和动态的方式分配内存空间。

静态分配:编译器在处理程序源代码时分配。一般程序员在源代码中直接定义了内存分配的大小,程序在运行的过程中,不会更改已经分配的空间。当分配的空间太少了,就会造成溢出;而内存分配过多时,则容易造成空间的浪费。

动态分配:程序在执行时调用malloc库函数申请分配。程序员可以跟据自己的需要来分配空间,不会造成空间的浪费。

静态与动态内存分配的主要区别如下:

(1)、静态内存分配是在程序执行之前进行的因而效率比较高,而动态内存分配则可以灵活的处理未知数目的。

(2)、静态对象是有名字的变量,可以直接对其进行操作;动态对象是没有名字的变量,需要通过指针间接地对它进行操作。

(3)、静态对象的分配与释放由编译器自动处理;动态对象的分配与释放必须由程序员显式的管理,通过调用malloc()和free两个函数来完成。

 

内存中的栈、堆、静态区:

(1)、栈区(stack)—— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

(2) 堆区(heap) ——一般由程序员分配释放, 若程序员不释放,程序结束时可能由os回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

(3)、静态区(全局区)(static)——静态变量和全局变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后有系统释放。

 

malloc/free函数

Malloc()函数用来在堆中申请内存空间,free()函数释放原先申请的内存空间。Malloc()函数是在内存的动态存储区中分配一个长度为size字节的连续空间。其参数是一个无符号整型数,返回一个指向所分配的连续存储域的起始地址的指针。当函数未能成功分配存储空间时(如内存不足)则返回一个NULL指针。

由于内存区域总是有限的,不能无限制地分配下去,而且程序应尽量节省资源,所以当分配的内存区域不用时,则要释放它,以便其他的变量或程序使用。

 

malloc函数的用法

调用形式: (类型说明符*)malloc(size)

功能:在内存的动态存储区中分配一块长度为"size"字节的连续区域。函数的返回值为该区域的首地址。 “类型说明符”表示把该区域用于何种数据类型。 (类型说明符*)表示把返回值强制转换为该类型指针。 “size”是一个无符号数。

例如: pc=(char *)malloc(100); 表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。

 

注意:当再次调用malloc函数分配空间时,如果已分配的空间后面有足够的空间时,则直接在其后面开辟所需要的空间。如果已分配的空间后面没有足够的空间时,则重新寻找足够的空间,并把旧空间的内容全部拷贝到新的空间,然后释放新的空间。

 

Free函数的用法

调用形式:free (pc);
功能:释放pc所指向的一块内存空间,pc是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc函数所分配的区域。在使用free函数后应该把被释放的空间赋值为空,例pc = NULL.

 

使用free()函数时,需要特别注意下面几点:

(1)调用free()释放内存后,不能再去访问被释放的内存空间。内存被释放后,很有可能该指针仍然指向该内存单元,但这块内存已经不再属于原来的应用程序,此时的指针为悬挂指针(可以赋值为NULL)。

(2)不能两次释放相同的指针。因为释放内存空间后,该空间就交给了内存分配子程序,再次释放内存空间会导致错误。

(3)不能用free来释放非malloc()、calloc()和realloc()函数创建的指针空间。

(4)在进行C语言程序开发中,malloc/free是配套使用的,即不需要的内存空间都需要释放回收。

(5)不能释放动态内存的一部分。

(6)不能对动态内存的越界使用。

 

malloc和realloc的区别

 函数malloc()和函数calloc() 的主要区别是前者不能初始化所分配的内存空间,而后者能。

malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之, 如果这部分内存曾经被分配过,则其中可能遗留有各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常进行,但经过一段时间(内存空间已经被重新分配)可能会出现问题。

calloc() 函数会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类 型或整数类型的元素分配内存,那麽这些元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那麽这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

以上便是我学习动态内存之后的一些个人理解,如果我的理解有错误,我希望能给我指出来,以便我能更好的理解内存空间分配。

2 0
原创粉丝点击