在新公司上班,发现有一段 代码类似:
char *p = malloc(sizeof(char) * strlen(file_name));
//to do
//
//
p = NULL;
free(p);
很奇怪,是不小心写成这样,还是有意写成这样的?我们编程常用的是先free(),再赋值NULL,这里居然是反着来,难道这样不会造成内存泄漏吗?
于是写了一个测试代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char *ptr = (char *)malloc(20);
char *tmp = ptr;
printf("ptr addr = 0x%x\n", ptr);
const char *str = "hello";
memcpy(ptr, str, strlen(str));
ptr = NULL;
free(ptr);
printf("ptr = %s\n", tmp);
return 0;
}
运行结果如下:
用gdb跟踪如下:
很明显malloc分配的地址0x602010内容还是在的,打印这个地址的内容,(x/8bc)打印8个单元的内容,每个单元为一个字节且用字符打印,其结果如下:
若是代码里先free(ptr);再ptr=NULL,会是怎样的呢?如下图:
free(ptr)后,其内容已经清空。更安全的作法是再 ptr=NULL,这样再使用时可以加判断,或是不小心再free(ptr)也不会有double free的问题。
man 3 free用法,是这样说的:
"The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed."
如果参数ptr是NULL,则不执行任何操作。