【发布时间】:2014-06-22 03:20:52
【问题描述】:
我能找到的所有关于释放“双”指针的东西都是指释放指向指针的指针,这不是我要说的。我已经想出了如何做到这一点。
这可能根本不是什么大事,但我注意到当我 free() 一个 int、char 或 float 指针时,该值被删除或替换为垃圾值,但是当我 free() double 指针时,值保持不变。
这是我测试过的代码:
int main()
{
int *p_a = malloc(sizeof(int));
*p_a = 1;
char *p_b = malloc(sizeof(char));
*p_b = 'b';
float *p_c = malloc(sizeof(float));
*p_c = 3.565;
double *p_d = malloc(sizeof(double));
*p_d = 7.77;
printf("Before 'free()':\n");
printf("A: %p\t%d\n", p_a, *p_a);
printf("B: %p\t%c\n", p_b, *p_b);
printf("C: %p\t%g\n", p_c, *p_c);
printf("D: %p\t%g\n", p_d, *p_d);
free(p_a);
free(p_b);
free(p_c);
free(p_d);
printf("\nAfter 'free()':\n");
printf("A: %p\t%d\n", p_a, *p_a);
printf("B: %p\t%c\n", p_b, *p_b);
printf("C: %p\t%g\n", p_c, *p_c);
printf("D: %p\t%g\n", p_d, *p_d);
return 0;
}
这产生了以下输出:
Before 'free()':
A: 0x8f2e008 1
B: 0x8f2e018 b
C: 0x8f2e028 3.565
D: 0x8f2e038 7.77
After 'free()':
A: 0x8f2e008 0
B: 0x8f2e018
C: 0x8f2e028 1.46175e-33
D: 0x8f2e038 7.77
这正常吗?我对malloc() 和free() 工作原理的理解是,当您malloc() 一个指针时,您会留出一些内存字节供指针指向。这是放在heap上,无法访问,直到free()d或在计算机上触发内存清理,它才会从heap上脱落,这不受控制用户。因此,当您free() 一个指针时,您基本上摆脱了指针与其指向的地址之间的关联,从而允许稍后使用该内存。
考虑到这一切,为什么double 指针仍然指向相同的值?
现在我想一想,为什么指针在free()s 之后有一个地址?
由于我是C 的初学者,因此非常感谢任何和所有的智慧和知识。感谢您的时间。
编辑:经过进一步测试和干预,我发现如果您输入一个超过 6 位的数字并在最后一位(例如 777.7777)上四舍五入为 double,在它是 free()d 之后,它会丢失它的舍入。
举例说明:
Before 'free()':
D: 0x8f2e038 777.778
After 'free()':
D: 0x8f2e038 777.777
这支持@rodrigo 的假设(在 cmets 中),因为 double 是 8 个字节 - 而 int、char 和 float 的 4 个字节 - free() 只修改第一个4 个字节,因此它不会丢失所有数据。
感谢大家的帮助!
【问题讨论】:
-
这是简单的未定义行为。
-
我没有在你的代码中看到任何双指针。
-
double *p_d = malloc(sizeof(double));是指向double值的指针。 -
是的。 C 是我们所说的“不安全”语言。如果您尝试访问不再属于您的内存,它不保证您会找到什么。所有
free()需要做的就是告诉操作系统该内存可用于其他用途。如果您在free()之后尝试访问内存,那不是任何人的问题,而是您的问题。 -
无论如何,知道
free()之后发生的事情实际上并不重要,这让人感到一种安慰。知道那些年轻、冒险的字节在他们面前充满了随机性,我可以高枕无忧了。也许double更喜欢久坐不动的生活方式。 :P
标签: c pointers memory-management double free