C语言细节之六:内存分配
1、gets(char *),fgets(char *)中的字符串指针类型参数,必须是之前已经对其分配了空间了的,否则不合法。
注意:gets()可以自动去除标准输入的换行,得到的字符串会以’\0’结束。
fgets()不能自动去除文件中的’\n’,会一直读到’\n’之后,且没有’\0’结尾,所以需要自己把’\n’换成’\0’。
2、strcat(char *, char *),strcpy(char *, char *),)的第一个字符串指针所指的空间必须要有包含第二个字符串大小的空间,且返回第一个字符串指针的值。
3、要使的函数返回的指针有意义,就必须指针所指的空间是:静态分配的缓冲区,或者是调用者传入的缓冲区,或者是malloc()获得的内存,绝对不能是函数内部的局部自动数组
4、malloc需要头文件stdlib.h
5、C中不需要对malloc返回的指针作类型转换。而C++中必须做
6、与malloc相关的常见的bug
(1) 应该用malloc(strlen(s) + 1),而不是malloc(strlen(s))
(2) 使用指向已经释放了的内存的指针
(3) 释放未从malloc获得的内存
(4) 两次释放同一个指针
(5) 试图重分配空指针
7、 调用free()后,实际上只是把指针所指的内存释放,而指针本身的值并不变,所以必须手动给指针赋NULL
8、多数的malloc/free的实现并不把释放的内存返回给操作系统,而是留着供同一个程序的后续malloc()使用
9、void *realloc(void *ptr, unsigned newsize)是对ptr重新分配地址空间,新的空间起始地址很有可能与原先的地址不同,但是ptr原来所指空间的内容会自动复制到新的内存空间中去。所以一定要用先用中间变量接住返回值(因为分配不成功时返回NULL),判断非NULL后再对ptr进行重新赋值。
注意:
如果realloc第一个参数指针为空指针NULL,这时等同于malloc。
如果realloc第一个参数指针不为空指针NULL,而第二个参数为0,则等同于free(),并返回NULL。
如果重新分配失败,则返回NULL,而原来的内存块维持不变(但是如果此时是直接用返回值对ptr作赋值,则很有可能要造成内存泄露!,所以一定要先用中间变量接住返回值,对返回值作有效性判断,然后再对ptr进行新地址赋值)。
10、calloc()与malloc()的关系
calloc(m,n)本质上等于 p = malloc(m*n);memset(p, 0, m*n);
填充的是全零,所以不能确保生成有用的空指针值或浮点零值。
free()可以安全释放calloc()分配的空间。