free函数和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));。
malloc()和free()函数区别

malloc()和free()函数区别一、malloc()和free()的基本概念以及基本用法:1、函数原型及说明:void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。
如果分配失败,则返回一个空指针(NULL)。
关于分配失败的原因,应该有多种,比如说空间不足就是一种。
void free(void *FirstByte):该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
2、函数的用法:其实这两个函数用起来倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个简单例子:程序代码:// Code...char *Ptr = NULL;Ptr = (char *)malloc(100 * sizeof(char));if (NULL == Ptr){exit (1);}gets(Ptr);// code...free(Ptr);Ptr = NULL;// code...就是这样!当然,具体情况要具体分析以及具体解决。
比如说,你定义了一个指针,在一个函数里申请了一块内存然后通过函数返回传递给这个指针,那么也许释放这块内存这项工作就应该留给其他函数了。
3、关于函数使用需要注意的一些地方:A、申请了内存空间后,必须检查是否分配成功。
B、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
C、这两个函数应该是配对。
如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。
释放只能一次,如果释放两次及两次以上会出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。
D、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。
c语言函数 malloc 与free 实现

c语言函数malloc 与free 实现在C语言中,malloc和free是用于动态内存分配和释放的两个重要函数。
这两个函数允许程序在运行时动态地分配和释放内存,使得程序更加灵活。
本文将深入探讨malloc和free函数的实现原理以及在实际编程中的应用。
1. malloc函数的实现1.1 malloc函数概述malloc(Memory Allocation的缩写)函数用于在堆区分配指定大小的内存空间。
其声明如下:void*malloc(size_t size);其中,size参数表示要分配的内存字节数。
malloc返回一个指向分配内存的指针,如果分配失败,则返回NULL。
1.2 malloc函数的实现原理malloc的实现通常基于操作系统提供的底层内存分配机制。
以下是一个简化的malloc实现示例:#include <stddef.h>void*malloc(size_t size){// 调用底层操作系统的内存分配函数void*ptr =os_allocate_memory(size);return ptr;}上述代码中,os_allocate_memory是一个虚构的函数,实际上会调用操作系统提供的内存分配函数,如brk或mmap等。
malloc返回操作系统分配的内存地址。
2. free函数的实现2.1 free函数概述free函数用于释放通过malloc分配的内存空间。
其声明如下:void free(void*ptr);其中,ptr是由malloc返回的指针。
调用free后,该内存空间将被释放,并可用于后续的内存分配。
2.2 free函数的实现原理free的实现通常涉及将释放的内存块标记为可用,并合并相邻的可用块,以防止内存碎片化。
以下是一个简化的free实现示例:#include <stddef.h>void free(void*ptr){// 标记释放的内存块为可用mark_memory_as_free(ptr);// 合并相邻的可用块coalesce_free_blocks();}上述代码中,mark_memory_as_free是一个虚构的函数,表示将释放的内存块标记为可用。
calloc(), malloc(), realloc(), free(),alloca()区别

这一行,作用完全等同于:
int* p = (int *)malloc(sizeof(int) * 10);
(5)关于alloca()函数
还有一个函数也值得一提,这就是alloca()。其调用序列与malloc相同,但是它是在当前函数的栈帧上分配存储空间,而不是在堆中。其优点是:当 函数返回时,自动释放它所使用的栈帧,所以不必再为释放空间而费心。其缺点是:某些系统在函数已被调用后不能增加栈帧长度,于是也就不能支持alloca 函数。尽管如此,很多软件包还是使用alloca函数,也有很多系统支持它。
(3)calloc函数的分配的内存也需要自行释放
calloc函数的功能与malloc函数的功能相似,都是从堆分配内存,它与malloc函数的一个显著不同时是,calloc函数得到的内存空间是经过初始化的,其内容全为0。calloc函数适合为数组申请空间,可以将size设置为数组元素的空间长度,将n设置为数组的容量。
(2)使用malloc函数分配的堆空间在程序结束之前必须释放
从堆上获得的内存空间在程序结束以后,系统不会将其自动释放,需要程序员来自己管理。一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露。
我们可以使用free()函数来释放内存空间,但是,free函数只是释放指针指向的内容,而该指针仍然指向原来指向的地方,此时,指针为野指针,如果此时操作该指针会导致不可预期的错误。安全做法是:在使用free函数释放指针指向的空间之后,将指针的值置为NULL。
所以,在代码中,我们必须将realloc返回的值,重新赋值给 p :
p = (int *) realloc(p, sizeof(int) *15);
甚至,你可以传一个空指针(0)给 realloc ,则此时realloc 作用完全相当于malloc。
c语言释放内存的函数

c语言释放内存的函数
首先,我们要先了解c语言中的内存管理,c语言中最常用的内存管理是动态内存管理,动态内存管理的一般流程是:申请一块内存,用完后再释放该块内存。
在C语言中释放内存关键步骤是调用函数free(),free()函数用于释放由malloc()函数申请的已分配但未使用的内存空间。
调用free()函数时,计算机将释放指定的block,该block以后可以由malloc()函数新分配,当free()函数成功执行后,该block的内存空间将被释放,但并不是真的被归还给操作系统,而是回到free list链表中,后面可能会由malloc()函数新分配。
free()函数的函数声明是:void free(void <*p>),表示返回值是没有的,所以在调用函数时,没有返回值。
free()函数只有一个参数,即由malloc()函数分配的指针,因此我们需要在调用free()函数时,把该指针作为参数传递给free()函数,表示要释放该指针指向的内存块;当free()函数成功执行后,原先由malloc()函数分配的内存块将被释放,释放之后,原先指向该内存块的指针p将失效,之后不能再引用该内存块。
调用free()函数时,只能free()由malloc()分配的内存block,若对任何其他变量使用free()函数,将导致未知的结果。
此外,释放已经释放的内存块也会导致未知的结果。
malloc与free的实现原理

malloc与free的实现原理malloc与free是C语言中最常用的内存管理函数,它们用于动态分配和释放内存。
malloc函数用于分配指定大小的连续内存空间,而free函数用于释放之前分配的内存空间。
malloc的实现原理:malloc的实现原理涉及操作系统内存管理机制,与具体的操作系统和体系结构有关。
通常情况下,C程序分配的内存空间是从操作系统的堆(Heap)中分配的,堆内存是动态分配的,它的大小会随着程序的运行而不断变化。
malloc在分配内存时,需要保证所分配的内存空间是连续的、足够的、未被使用的,并且能够存储所需的数据。
对于malloc函数的实现,有两种基本方式:1.使用系统调用:malloc函数直接通过系统调用向操作系统申请一段连续的内存空间。
当应用程序申请内存时,操作系统会搜索一个可用的内存块,然后返回指向此块的指针。
此时,在应用程序可以使用此内存空间来存储数据。
这种方式的优点是可靠性高,但是效率相对较低。
2.使用内存池:malloc函数通过维护一个内存池来管理内存,程序内部堆内存,并从池中分配内存块。
当应用程序需要使用内存时,它会从内存池中获取一个已分配但未使用的内存块。
当内存块不再需要时,它将被释放并回收到内存池中,以供另一个内存块使用。
这种方式的优点是效率高,但是管理成本高。
free的实现原理:当应用程序使用完分配的内存空间,应该立即将其释放以便其他程序可以使用。
free函数将已分配的内存块标记为未占用的内存块,并将其返回给系统供其他程序使用。
free实现的核心原理是如何跟踪已分配的内存空间,以便正确地标记和释放它们。
free函数需要知道正在释放的内存块的大小和它分配的地址。
通常情况下,这些信息都存储在管理头(Management Header)中,这是一个特殊的结构体,位于每个已分配的内存块的前面。
这个结构包含对分配的内存块的描述,包括大小、指向下一个内存块的指针和认证信息等。
深入探究C中的malloc()和free()函数

深入探究C中的malloc()和free()函数作者:陆金江来源:《计算机光盘软件与应用》2013年第21期摘要:C中的malloc()函数和free()函数是一对可以动态分配内存与释放内存的函数,本文将从语法基础、应用场合、实现原理等方面对这两个函数进行细致深入地阐述。
关键词:C;malloc()函数;free()函数中图分类号:TP312.11 malloc()和free()的语法基础C语言中可以用malloc()函数在内存中动态分配一块连续空间,分配空间大小由指定参数决定。
其函数原型为:void *malloc(unsigned int size);返回值是所分配区域的首地址。
如果内存分配失败(例如内存空间不足)则返回空指针NULL。
如:int *p = malloc(50); //开辟50字节的内存空间,将空间首地址赋给指针变量pmalloc()的返回值类型为void*,很多人喜欢像下面这样将返回值进行强制类型转换:int *p = (int*) malloc(50);其实没有必要,void*类型的指针是可以不经强制转换,赋给所有类型指针变量的。
如果不再需要malloc()分配的内存空间,可以通过free()来释放内存。
如:free(p); //释放 p 所指向的内存区域2 malloc()的应用场合malloc()经常被用于分配执行前还不确定大小的数组的内存区域、动态分配结构体的内存区域等。
如在不确定书名长短时,为了避免声明的数组长度过长造成空间浪费,可以用下列方式,在确定了书名长度后,给它分配必要的内存区域。
char *title;title = malloc(sizeof(char)*len); //len为书名的实际长度再如,数据结构中,在构建链表时,要用malloc()为链表中的每一个结点动态分配空间。
3 malloc()和free()的实现原理malloc()是在内存中称为“堆”的空间中进行分配的,堆的特点就是可以动态地、在运行时进行内存分配,并且可以通过任意的顺序释放内存。
c语言动态分配内存函数

c语言动态分配内存函数C语言是一门很古老但依然强大的编程语言,作为一门底层语言,C语言与内存密不可分。
在C语言中,内存分配是一个非常重要的概念。
C语言提供了很多函数来进行内存管理,其中最为常用的便是动态分配内存函数。
本文将围绕动态分配内存函数来进行分步介绍。
1. malloc函数malloc函数是C语言中最为基本的动态分配内存函数,该函数会在堆内存中分配一块指定大小的内存块,并返回该内存块的首地址。
下面是malloc函数的基本语法:void* malloc(unsigned int size);其中,size参数表示要分配的内存块的大小,函数返回一个void型指针,该指针指向已分配的内存块的首地址。
使用malloc函数的方法如下所示:int* arr = (int*)malloc(sizeof(int) * 10);该语句将在堆内存中分配一块大小为40字节(即10个int型变量所占用的内存)的内存块,并将arr指针指向该内存块的首地址。
2. calloc函数calloc函数与malloc函数类似,也是用于动态分配内存的函数。
但与malloc函数不同的是,calloc函数还会对分配的内存块进行初始化。
同时,calloc函数的语法也略有不同:void* calloc(unsigned int num, unsigned int size);其中,num参数表示要分配的内存块的数量,size参数则表示每个内存块的大小。
使用calloc函数的方式如下所示:int* arr = (int*)calloc(10, sizeof(int));该语句将在堆内存中分配一块大小为40字节(即10个int型变量所占用的内存)的内存块,并将该内存块中每个字节都初始化为0,并将arr指针指向该内存块的首地址。
3. realloc函数realloc函数是用于重新分配已经分配的内存块的函数。
该函数接受两个参数,第一个参数是原内存块的地址,第二个参数是新的内存块大小。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
malloc原型:extern void *malloc(unsigned int num_bytes);用法:#include <malloc.h>或#include<stdlib.h>功能:分配长度为num_bytes字节的内存块说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
malloc的语法是:指针名=(数据类型*)malloc(长度),(数据类型*)表示指针.举例:// malloc.c#include <syslib.h>#include <malloc.h>main(){char *p;clrscr(); // clear screenp=(char *)malloc(100);if(p)printf("Memory Allocated at: %x",p);elseprintf("Not Enough Memory!\n");if(p)free(p);getchar();return 0;}malloc()函数的工作机制malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。
调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。
然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。
接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。
调用free函数时,它将用户释放的内存块连接到空闲链上。
到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。
于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。
浅析malloc()的几种实现方式malloc()是C语言中动态存储管理的一组标准库函数之一。
其作用是在内存的动态存储区中分配一个长度为size的连续空间。
其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。
动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。
动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
本文简单介绍动态内存分配函数malloc()及几种实现方法。
1.简介malloc()是C语言中动态存储管理的一组标准库函数之一。
其作用是在内存的动态存储区中分配一个长度为size的连续空间。
其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。
还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。
所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。
2.函数说明C语言的动态存储管理由一组标准库函数实现,其原型在标准文件<stdlib.h>里描述,需要用这些功能时应包含这个文件。
与动态存储分配有关的函数共有四个,其中就包括存储分配函数malloc()。
函数原型是:void *malloc (size_t n);这里的size_t 是标准库里定义的一个类型,它是一个无符号整型。
这个整型能够满足所有对存储块大小描述的需要,具体相当于哪个整型由具体的C系统确定。
malloc的返回值为(void *)类型(这是通用指针的一个重要用途),它分配一片能存放大小为n的数据的存储块,返回对应的指针值;如果不能满足申请(找不到能满足要求的存储块)就返回NULL。
在使用时,应该把malloc的返回值转换到特定指针类型,赋给一个指针。
注意,虽然这里的存储块是通过动态分配得到的,但是它的大小也是确定的,同样不允许越界使用。
例如上面程序段分配的块里能存n个双精度数据,随后的使用就必须在这个范围内进行。
越界使用动态分配的存储块,尤其是越界赋值,可能引起非常严重的后果,通常会破坏程序的运行系统,可能造成本程序或者整个计算机系统垮台。
下例是一个动态分配的例子:#include <stdlib.h>main(){int count,*array; /*count是一个计数器,array是一个整型指针,也可以理解为指向一个整型数组的首地址*/if((array(int *) malloc (10*sizeof(int)))==NULL){printf("不能成功分配存储空间。
");exit(1);}for (count=0;count〈10;count++) /*给数组赋值*/array[count]=count;for(count=0;count〈10;count++) /*打印数组元素*/printf("%2d",array[count]);}上例中动态分配了10个整型存储区域,然后进行赋值并打印。
例中if((array(int *) malloc (10*sizeof(int)))==NULL)语句可以分为以下几步:1)分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针2)把此整型指针地址赋给array3)检测返回值是否为NULL3.malloc()工作机制malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。
调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。
然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。
接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。
调用free函数时,它将用户释放的内存块连接到空闲链上。
到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。
于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。
4.malloc()在操作系统中的实现在 C 程序中,多次使用malloc () 和free()。
不过,您可能没有用一些时间去思考它们在您的操作系统中是如何实现的。
本节将向您展示malloc 和free 的一个最简化实现的代码,来帮助说明管理内存时都涉及到了哪些事情。
在大部分操作系统中,内存分配由以下两个简单的函数来处理:void *malloc (long numbytes):该函数负责分配numbytes 大小的内存,并返回指向第一个字节的指针。
void free(void *firstbyte):如果给定一个由先前的malloc 返回的指针,那么该函数会将分配的空间归还给进程的“空闲空间”。
malloc_init 将是初始化内存分配程序的函数。
它要完成以下三件事:将分配程序标识为已经初始化,找到系统中最后一个有效内存地址,然后建立起指向我们管理的内存的指针。
这三个变量都是全局变量:清单 1. 我们的简单分配程序的全局变量int has_initialized = 0;void *managed_memory_start;void *last_valid_address;如前所述,被映射的内存的边界(最后一个有效地址)常被称为系统中断点或者当前中断点。
在很多UNIX? 系统中,为了指出当前系统中断点,必须使用sbrk(0) 函数。
sbrk 根据参数中给出的字节数移动当前系统中断点,然后返回新的系统中断点。
使用参数0 只是返回当前中断点。
这里是我们的malloc 初始化代码,它将找到当前中断点并初始化我们的变量:清单 2. 分配程序初始化函数/* Include the sbrk function */#includevoid malloc_init(){/* grab the last valid address from the OS */last_valid_address = sbrk(0);/* we don't have any memory to manage yet, so*just set the beginning to be last_valid_address*/managed_memory_start = last_valid_address;/* Okay, we're initialized and ready to go */has_initialized = 1;}现在,为了完全地管理内存,我们需要能够追踪要分配和回收哪些内存。
在对内存块进行了free 调用之后,我们需要做的是诸如将它们标记为未被使用的等事情,并且,在调用malloc 时,我们要能够定位未被使用的内存块。
因此,malloc 返回的每块内存的起始处首先要有这个结构:清单 3. 内存控制块结构定义struct mem_control_block {int is_available;int size;};现在,您可能会认为当程序调用malloc 时这会引发问题——它们如何知道这个结构?答案是它们不必知道;在返回指针之前,我们会将其移动到这个结构之后,把它隐藏起来。
这使得返回的指针指向没有用于任何其他用途的内存。
那样,从调用程序的角度来看,它们所得到的全部是空闲的、开放的内存。
然后,当通过free() 将该指针传递回来时,我们只需要倒退几个内存字节就可以再次找到这个结构。
在讨论分配内存之前,我们将先讨论释放,因为它更简单。
为了释放内存,我们必须要做的惟一一件事情就是,获得我们给出的指针,回退sizeof(structmem_control_block) 个字节,并将其标记为可用的。
这里是对应的代码:清单 4. 解除分配函数void free(void *firstbyte) {struct mem_control_block *mcb;/* Backup from the given pointer to find the* mem_control_block*/mcb = firstbyte - sizeof(struct mem_control_block);/* Mark the block as being available */mcb->is_available = 1;/* That's It! We're done. */return;}如您所见,在这个分配程序中,内存的释放使用了一个非常简单的机制,在固定时间内完成内存释放。