malloc()函数
1、函数原型及说明:
头文件:#include <stdlib.h>
malloc() 函数用来动态地分配内存空间其原型为:
1 | void* malloc (size_t size); |
参数说明:
- size 为需要分配的内存空间的大小,以字节(Byte)计。
- size -t 是无符号整数类型。
函数说明:
malloc() 在堆区分配一块指定大小的内存空间,用来存放数据。
这块内存空间在函数执行完成后不会被初始化,它们的值是不确定的。
如果希望在分配内存的同时进行初始化,请使用 calloc() 函数。
返回值:
分配成功返回指向该内存的地址,失败则返回NULL。
关于分配失败的原因,应该有多种,比如说空间不足就是一种。
1 | void free(void *FirstByte); |
该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
2、函数的用法:
向malloc申请的空间的大小是以字节为单位的。
- 返回的结果是
void*
,需要类型转换为自己需要的类型 。
1 | int* num; |
程序示例:
1 | /* malloc example: random string generator*/ |
该程序生成一个由用户指定的长度的字符串,由字母字符组成。此字符串的可能长度仅受malloc可用内存量的限制。
3、注意事项:
- malloc的返回值是一个指针,指向一段可用内存的起始地址。
- 申请了内存空间后,必须检查是否分配成功。
- 当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
- malloc() 和 free() 这两个函数应该配对。如果申请后不释放会出现内存泄露。
- 虽然malloc()函数的类型是(void*),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。
memset()函数
1、函数原型及说明:
头文件:#include <string.h>
memset() 函数用来将指定内存的前n个字节设置为特定的值,其原型为:
1 | void * memset( void * ptr, int value, size_t num ); |
参数说明:
- ptr 为要操作的内存的指针。
- value 为要设置的值。你既可以向 value 传递 int 类型的值,也可以传递 char 类型的值,int 和 char 可以根据 ASCII 码相互转换。(最终解释为 unsigned char)
- num 为 ptr 的前 num 个字节。
- size_t 就是unsigned int。
函数说明: memset() 会将 ptr 所指的内存区域的前 num 个字节的值都设置为 value,然后返回指向 ptr 的指针。
返回值: 返回指向 ptr 的指针。
2、函数用法:
memset() 可以将一段内存空间全部设置为特定的值,所以经常用来初始化字符数组。例如:
1 | char str[20]; |
对整型数组初始化:
1 | int* num; |
3、注意事项:
memset() 中的第三个参数一定要使用 sizeof 操作符,因为每个系统下对类型长度的定义可能不一样。
memset() 中的第一个参数一定要是一个已知的、已经被分配内存的地址,否则会出错。
最重要的一点: 对于单字节数据类型(char)可以初始化为任意支持的值,多字节数据类型只能初始化为 0。
原因:
memset是按照字节对待初始化空间进行初始化的,也就是说,函数里面的第二个参数的那个初值(一般为0)是按照一个个字节往第一个参数所指区域赋值的,所以,对于单字节数据类型(char)可以初始化为任意支持的值,都没有问题。
但是对于多字节数据类型只能初始化为0,而不能初始化成别的初值,因为对所有字节按任意顺序赋值0的结果都是0,而如果初始化为其他的值,就会一个字节一个字节的进行赋值,从而出现奇怪的结果。如果将 int 类型数组初始化为1,那么因为int一般是4个字节,那么相当于将一个int元素初始化成了 0000 0001 0000 0001 0000 0001 0000 0001,
这样对于一个int元素肯定不是1,而是一个很大的数,结果出乎意料。