C语言内存分配

【搬运工】浅谈c语言中的内存分配

在C语言中,根据数据在内存中存在的时间(生存期)不同,将内存空间分为三个区:

1.程序区:用于存储程序的代码,即程序的二进制代码;

2.静态存储区:用于存储全局变量和静态变量,这些变量的空间在程序编译时就已经分配好了;

3.动态存储区:用于在程序执行时分配的内存,又分为:堆区(heap)和堆栈区(stack)两种。

                 堆区:用于动态内存分配,程序运行时由内存分配函数在堆上分配内存。在C语言中,只要使用指针才能动态的分配内存

                 堆栈区:在函数执行时,函数内部的局部变量和函数参数的存储单元的内存区域,函数运行结束时,这些内存区域会自动释放。

动态内存分配

       在C语言中用内存分配函数来实现内存的动态分配,这些函数有:malloc()、calloc()和realloc()函数。

(1).malloc(): 使用这个函数时需要包含头文件<stdlib.h>。使用该函数需要指定要分配的内存字节数作为参数,函数返回值为所分配内存的第一个字节的地址。因为返回值是一个地址,这里需要用指针。例如:

int *pNumber=(int *) malloc(100);

这条语句分配了100个字节的内存,并把这个内存块的地址赋给pNumber,这个内存块保存25个int值,每个int占4个字节。如果不能分配请求的内存,malloc()会返回一个null指针。所以使用之前,要先判断一下是否为null。例如:

if(pNumber==null){  //提示内存不足 }

有时使用sizeof运算符分配内存,如:pNumber=(int *)malloc(25*sizeof(int));该例子分配了25个int型大小的内存,即25*4=100个字节;

(2)calloc():它把内存分配为给定大小的数组,并且初始化了分配的内存,每位都为0;该函数需要两个参数:数组元素的个数和数组元素占用的字节数。例如:

   int *pNumber=(int *)calloc(25,sizeof(int));

释放动态分配的内存:

堆上分配的内存会在程序结束时自动释放,但最好是在使用完这些内存后立即释放。如果不释放,可能会引起内存泄露。使用free()函数释放内存,参数是内存地址。

free(pNumber);

【搬运工】 C语言内存分配函数malloc、calloc和realloc

C语言中常用的内存分配函数有malloc、calloc和realloc等三个,其中,最常用的肯定是malloc,这里简单说一下这三者的区别和联系。

1、声明

这三个函数都在stdlib.h库文件中,声明如下:

void* realloc(void* ptr, unsigned newsize); 
void* malloc(unsigned size); 
void* calloc(size_t numElements, size_t sizeOfElement);

它们的功能大致类似,就是向操作系统请求内存分配,如果分配成功就返回分配到的内存空间的地址,如果没有分配成功就返回NULL。

2、功能

malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。 
calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。 
realloc(*ptr,size):将ptr内存大小增大或缩小到size。

需要注意的是realloc将ptr内存增大或缩小到size,这时新的空间不一定是在原来ptr的空间基础上,增加或减小长度来得到,而有可能(特别是在用realloc来增大ptr的内存空间的时候)会是在一个新的内存区域分配一个大空间,然后将原来ptr空间的内容拷贝到新内存空间的起始部分,然后将原来的空间释放掉。因此,一般要将realloc的返回值用一个指针来接收,下面是一个说明realloc函数的例子。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdlib.h>
int main()
{
     //allocate space for 4 integers
     int *ptr=( int *)malloc( 4 *sizeof( int ));
 
     if (!ptr)
     {
         printf( "Allocation Falure!\n" );
         exit( 0 );
     }
 
     //print the allocated address
     printf( "The address get by malloc is : %p\n" ,ptr);
 
     //store 10、9、8、7 in the allocated space
     int i;
     for (i= 0 ;i< 4 ;i++)
     {
         ptr[i]= 10 -i;
     }
 
     //enlarge the space for 100 integers
     int *new_ptr=( int *)realloc(ptr, 100 *sizeof( int ));
 
     if (!new_ptr)
     {
         printf( "Second Allocation For Large Space Falure!\n" );
         exit( 0 );
     }
 
     //print the allocated address
     printf( "The address get by realloc is : %p\n" ,new_ptr);
 
     //print the 4 integers at the beginning
     printf( "4 integers at the beginning is:\n" );
     for (i= 0 ;i< 4 ;i++)
     {
         printf( "%d\n" ,new_ptr[i]);
     }
     return 0 ;
}</stdlib.h></stdio.h>
运行结果如下:

 

从上面可以看出,在这个例子中新的空间并不是以原来的空间为基址分配的,而是重新分配了一个大的空间,然后将原来空间的内容拷贝到了新空间的开始部分。

3、三者的联系

calloc(n,size)就相当于malloc(n*size),而realloc(*ptr,size)中,如果ptr为NULL,那么realloc(*ptr,size)就相当于malloc(size)。

【搬运工】 【C解析之三】C语言的内存分配

C解析之三运行时内存分配

     前言:以别样的角度解析C。
        C语言的内存是让很多初学C编程的同学感到混乱与头疼的问题,受此困扰很难对C有清晰全面的把握,打击学习的积极性。然而,一般基础教材对C运行时内存往往避而不谈,高级参考资料的长篇大论同样让人抓不住要点。接下来,我就给各位同学解开C语言运行时内存的面纱。
         内存空间与房间:  电脑的内存,通常有2G,4G等大小,这些空间由你的操作系统分配给你编写的C程序使用。当C程序运行时,便从操作系统得到一块内存空间,但这块空间怎么分配与管理,是我们要说的重点。类比个人的房间,毫无规则的摆放你的物品将会一团糟,显然我们需要有 某种规则 以便有条理的摆放与管理你的物品。对C语言而言,这个 某种规则 便是C语言 内存管理机制
         1.分区
                   代码区
                    静态区
                    堆
                    空闲内存
                    栈
               明确的分区是管理的前提,只有我们确定了房间分那几块区域,才能确定下一步区域摆放哪些物品。确定分区后,我们需要一份清单,记录分类摆放的规则:
           1.代码区:存放程序执行的代码
           2.静态区:全局变量和静态变量(有的同学可能有更深的认识静态区可以 细分为:
                                                     1.非初始化数据段:存放未初始化的全局变量和静态变量。
                                                     2. 初始化的数据: 存放 初始化的全局变量和静态变量。
           3.堆:动态分配区域,malloc, calloc, realloc等函数
           4.空闲内存:堆栈式可延伸的,空闲内存提供堆向下与栈向上需要的空间
           5.栈:局部变量及每次函数调用时返回地址、以及调用者的环境信息
 C语言设计了这个规则,并严格的为每个程序分配与管理内存,使程序的运行井然有序。一个物品摆放整齐的房间,寻找某件物品会更快,C语言的内存分配机制同样如此,使其拥有更优良的性能。示例如下:
            
            2.更多的思考
           变量在内存分配的不同区域,有不同的特性。比如分配在静态区的数据,可以在编译时直接写入代码,以获得更高访问数据的速度。C在堆里分配的空间必须由程序员手动释放,否则会造成内存的泄露等更多进一步的了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值