我能找到的所有东西都指的是释放' double'指针指的是释放指针的指针,这不是我所说的。我已经想出了如何做到这一点。
它可能根本不是一件大事,但我注意到当我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
上,无法访问它,并且在heap
或计算机上触发内存清理之前它不会离开free()
,这不受用户控制。因此,当您free()
指针时,您基本上摆脱了指针与其指向的地址之间的关联,允许稍后使用该内存。
鉴于这一切,为什么double
指针仍然指向相同的值?
现在我考虑一下,为什么指针在free()
之后根本就有一个地址?
由于我是C
的初学者,所以非常感谢任何智慧和知识。感谢您的时间。
编辑:经过进一步的测试和干预后,我发现如果你输入一个数字超过6位的数字并在最后一个数字(例如777.7777)上为{{1}在它double
之后,它就会失去它的四舍五入。
举例说明:
free()
这支持@ rodrigo的假设(在评论中),因为Before 'free()':
D: 0x8f2e038 777.778
After 'free()':
D: 0x8f2e038 777.777
是8个字节 - 而不是double
,int
和char
4个字节 - float
仅修改前4个字节,因此不会丢失所有数据。
感谢大家的帮助!
答案 0 :(得分:7)
我对malloc()和free()如何工作的理解是,当你指向malloc()时,你需要为指针指向一些内存字节。
你没有指向一个指针。你malloc一块内存。 malloc返回的值是指向该内存的指针。所以,让我们改一下。
我对malloc()和free()如何工作的理解是当你使用malloc()一块内存时,你会留出一些字节的内存;返回的指针指向该内存块的开头。
正确。
这个[内存块]放在堆上
正确;将堆视为长期随机存取存储。
无法访问的地方
这是错误的或荒谬的。哪些什么无法访问,以及由谁?
它[内存块]在释放之前不会脱离堆()d
malloc分配的内存块保留供您的程序使用,直到调用free
为止。要释放块,可以调用free并传递最初从malloc
返回的指针,是的。
或计算机上触发内存清理,不受用户控制
这又是不连贯的。现代操作系统使用虚拟内存。当一个进程被销毁时,整个虚拟地址空间就会消失。
当你释放()指针时,你基本上摆脱了指针和它指向的地址之间的关联,允许稍后使用该内存。
不不不不不。这是你误解的关键。
通过将malloc最初返回的指针传递给free来释放内存块。这释放了内存块,然后如果进程中的其他代码要求内存,则允许malloc再次将其移出。
但是free不会改变指针指向的地址!指针继续指向一个地址;该地址现在无效!取消引用指向无效内存的指针称为"未定义的行为"在C中,字面上任何都可能发生。你的程序会崩溃。您可以获得以前的价值。您的密码可以通过电子邮件发送给北极秘密巢穴中的黑客。 任何都可能发生,所以不要那样做。
(巧合的是,我今天早些时候写了一篇关于这个主题的博客文章,该文章将于周三发布,所以请关注我的博客了解详情。)
鉴于这一切,为什么双指针仍然指向相同的值?
未定义的行为意味着任何事情都可能发生。仍然指向相同值的指针正在发生,发生的事情是发生的任何事情的一个子集。
现在我想一想,为什么指针在free()之后根本就有一个地址?
指针存储在变量中。 您没有更改变量的值。变量会保留其值,直到您更改它们为止。
我在哪里可以阅读更多内容?
您可能会对这个高度相关的问题感兴趣。
Can a local variable's memory be accessed outside its scope?
该问题与您的问题相同,除非在给定的问题中指针指向堆栈,而不是指向堆。但逻辑是相同的:取消引用指向弹出堆栈帧的指针是未定义的行为,就像取消引用指向空闲块的指针是未定义的行为一样。任何事情都可能发生。
答案 1 :(得分:2)
基本上,一旦释放指针,就不应再使用它指向的数据了。
malloc 为您分配一些您负责编写和读取的内存。那块“属于”你,但它只是一个租金!
释放该块之后,它又回到了系统中。如上所述,使用该数据是未定义的行为:预期结果(好像没有免费),错误的结果,崩溃......
根据双重问题,尝试将释放(D转换为A)反转,看看会发生什么......(无论如何, malloc 不认识你打算在那个空间放一个 double 。