对于一段内存的数存,该如何解释,是依赖于数据类型,需要使用 malloc,其使用语法如下:
void *
malloc(size_t size);
函数 malloc 包含在头文件为 stdlib.h 的头文件中,使用前需要把它包含进来,其返回值是 void *,其含义是:返回值自定义,有我们用户决定,定义的是接收整型的内存,返回值就是整型的指针,定义的是接收字符型的内存,返回值就是字符型的指针.下面是一个例子:
int *pMyInt = (int*)malloc(sizeof(int))
在这里,我们使用的是int*,所以,malloc分配的空间所存储的类型就是int型,其声明的pMyInt所指向的事malloc所份哦诶内存的首地址
内存分配之后,要判断内存是否申请成功。在这里,我们使用if语句判断:若内存为空,则证明内存申请成功,否则,需要终止程序.
if (NULL != myString)
{
printf("Allocate memory error!");
exit(1);
内存申请成功后,需要对内存进行初始化,需要使用 memset 函数,其存在的库为 String, 所以文件要包含 String.h 这个头文件,其基本语法:
void *
memset(void *b, int c, size_t len);
memset 的功能是实现内存的初始化, void *b 是字符串数组的名字,也是地址, c 是具体的地址, len 是指的字符的个数,下面就是一个实例, myString 是字符数组的名字,0x00是初始化的首地址, nSize 是申请的个数,可以是具体值,这里的是根据用户的输入而设定的一个值.
memset(myString,0x00,nSize);
接下来就是要由用户输入想要的字符个数,以及字符.在苹果 Mac 下的 Iterm 中,用苹果的键盘输入的话,会涉及到键盘缓冲区的概念.具体就是输入字符时,需要输入一个字符,然后换行,再输下一个,当从循环中再次执行时,系统就会默认遇到回车键,就是’\n’, 这时候就会跳过去此次循环.等到下次在执行是才会继续让输入,本质就是每隔一个字符存放位存放,导致内存浪费,用户的目的也达不到.
于是, fpurge 函数就应运而生了,其语法结构为:
int
fpurge(FILE *stream);
fpurge函数的作用是刷新文件流,当用 fpurge(stdin); 时,就是刷新键盘的输入缓冲区,这样就不存在’\n’ 的问题啦
内存使用之后,一定要记得释放掉内存,因为 malloc 申请的内存是从堆中申请的,是用户唯一能手动管理的内存部分,如果使用后不释放掉,就会一直占用内存.长此以往,我们将会无内存可用
free(myString);
释放完内存后,需要把前面定义的字符型指针给释放掉.愿意很简单,不设为空的话,后面在调用指针 myString 时,它仍指向 malloc 分配的内存首部,然而 malloc 分配的内存已经释放掉了,这样就会出现错误.
以下就是我在学习内存分配中写的小例子:
本例在苹果的系统下的 Iterm 中运行的.它使用了 argv[1],指的是在命令行输入的第二个字符,用户在命令行就输入需要的字节大小
1 #include
2 #include
3 #include
4
5 //根据用户从键盘输入的内容,然后在屏幕上打印
6
7 int main(int argc,const char *argv[])
8 {
9 char *myString = NULL;
10 char myChar;
11 int j =0;
12 myChar = fgetc(stdin);
13 int nSize = atoi(argv[1]);
14
15 myString = (char*)malloc(sizeof(char) * nSize);
16 //内存申请好之后,需要判断是否为空,若为空,则证明内存申请成功
17 if (NULL != myString)
18 {
19 printf("Allocate memory error!");
20 exit(1);
21 }
22 //内存分配好之后,需要进行内存的初始化
23 memset(myString,0x00,nSize);
24 for (int i = 0;i < nSize - 1;i++)
25 {
26 //使用 fpurge 来清空键盘缓冲区中的记忆
27 fpurge(stdin);
28 myString[i] = myChar;
29 myChar = fgetc(stdin);
30 }
31
32 printf("the myString is %s\n",myString);
33 //内存使用之后,一定要记得释放掉内存,因为 malloc 申请下的内存都是在堆中申请的,如果不释放掉, 会一直占用内存空间,长此以往,我们将没有可用的内存
34 free(myString);
35 //此处把 myString 设为空的原因就是,如果不设为空,后面在重新使用时, myString 仍指向原来的地址,而那地址里的内容已释放,就会出现错误,所以 myString 设为空
36 myString = NULL;
37 return 0;
38
39 }