我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows程序员如何学习Linux环境内存管理。由于很多程序在Windows环境下开发好后,还要部署到Linux服务器上去,所以作为Windows程序员有必要学习Linux环境的内存管理知识。
通过大学的编程基础学习,相信大家已经了解到静态内存主要针对程序中的各种变量,当在程序中定义变量时,编译器就为其分配了内存,当变量的作用域结束时,会自动释放该变量所在的内存。由此看来,静态内存的分配与释放都不需要程序员规定,因此也就无须考虑内存的管理问题;而动态内存的分配与释放完全由程序员自行决定,因此有很多需要考虑的内存管理方面的操作。下面就介绍关于动态内存管理的基本操作。
分配内存
计算机的内存空间都是通过指针进行访问的,而指针对于正确地分配动态内存空间来说又是十分重要的。关于动态内存的分配所使用的操作函数,在这里主要介绍malloc()、calloc()、realloc()和memset()函数的基本用法。
1. malloc()函数
函数原型为:
void *malloc(unsigned int size);
该函数的功能是分配长度为size字节的内存块。
如果分配成功,则返回指向被分配内存的指针;否则返回空指针NULL。当内存不再使用时,要使用 free()函数释放内存块。例如,使用 malloc()函数获得一块内存空间,内存空间的大小与返回的指针类型由程序员根据需要自行规定,代码如下:
void main()
{
long* buffer;
buffer =(long*)malloc(500); /获得一块长整型数组空间
free(buffer); /释放内存空间
}
2. calloc()函数
函数原型为:
void *calloc(unsigned n,unsigned size);
该函数的功能是在内存的动态区存储中分配n个长度为size的内存块。
如果分配成功,则返回指向被分配内存的指针;否则返回空指针NULL。同样,在内存不再使用时要用free(函数释放内存块。
用calloc()函数可以为一维数组开辟动态存储空间,n为数组元素的个数,每个元素长度为size。
例如,使用 calloc()函数获得一块长整型数组空间,代码如下:
void main()
{
long* buffer;
buffer =(long *)calloc(100,sizeof(long)); //获得一块长整型数组空间
free(buffer); //释放内存空间
}
3. realloc()函数
函数原型为:
void *realloc(void *mem_address,unsigned int newsize);
该函数的功能是调整 mem_address所指内存区域的大小为 newsize长度。
如果重新分配内存成功,则返回指向被分配内存的指针;否则返回空指针NULL。同样,当内存不再使用时,应用free()函数将内存空间释放。
当参数 mem_address 指向 NULL时,即调整空指针所指向的内存区域的大小为 newsize长度,此时 realloc()函数的功能与malloc()函数相同。若参数 newsize为0,即要调整成的长度为0时, realloc()函数所实现的功能就相当于free()函数,释放掉该内存区块。
可以用VI编辑器中编写一个简单的C语言程序test.c,利用realloc()函数重新分配一块内存空间。程序的代码如下:
#include<stdlib.h>
#include<stdio.h>
main()
{
char *p;
p=(char*)malloc(100); /*为指针p开辟一个内存空间*/
if(p) /*判断内存分配成功与否*/
printf("内存分配情况如下: %x",p);
else
printf("内存无法分配\n");
getchar();
p=(char*)realloc(p,256); /*调整p内存空间从100字节到256字节*/
if(p)
printf("内存重新分配情况如下: %x",p);
else
printf("内存无法分配\n");
free(p); /*释放p所指向的内存空间*/
getchar();
return 0;
}
程序的运行效果如所示。
$ gcc -o test test.c
$./test
内存分配情况如下: 2df58010
内存重新分配情况如下: 2df588a0
$
4. memset()函数
函数原型为:
void *memset(void *s, char ch,unsigned n);
该函数的功能是设置s中的所有字节为ch,s数组的大小为n。
可以用VI编辑器中编写一个简单的C语言程序test.c,利用memset()函数的功能,用字符“*”替换数组s中的字符串。
#include<string.h>
#include<stdio.h>
int main(void)
{
char s[]="welcome to microsoft\n"; /*定义一个字符数组s*/
printf("输出原来的字符:%s\n",s); /*输出字符数组中的内容*/
memset(s,'a',strlen(s)-1); /*设置s数组中的字符串内容为“a”*/
printf("输出之后的字符:%s\n",s); /*输出此时的字符数组内容*/
return 0;
}
程序在Linux系统中的运行效果如下所示。
$ gcc -o test test.c
$ . /test
输出原来的字符: welcome to microsoft
输出之后的字符: aaaaaaaaaaaaaaaaaaaa
$
释放内存
通过 malloc()、calloc()和 realloc()函数分配完动态内存后,在程序中可以使用这些内存空间,在使用完动态内存后,一定要使用free()函数释放掉该块内存空间,以免造成内存泄露等问题。当释放掉内存后,原来指向内存空间的指针就会变成悬空的指针,这时再使用该指针时就会发生错误。
free()函数的原型为:
void free( void *memblock);
参数memblock表示要被释放的内存区块。
作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。