Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 释放指向'的指针;双倍';价值_C_Pointers_Memory Management_Double_Free - Fatal编程技术网

C 释放指向'的指针;双倍';价值

C 释放指向'的指针;双倍';价值,c,pointers,memory-management,double,free,C,Pointers,Memory Management,Double,Free,我能找到的所有关于释放“双”指针的东西都是指将指针释放到指针,这不是我要说的。我已经知道怎么做了 这可能根本不是什么大事,但我注意到,当我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

我能找到的所有关于释放“双”指针的东西都是指将指针释放到指针,这不是我要说的。我已经知道怎么做了

这可能根本不是什么大事,但我注意到,当我
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()
一个指针时,你会为指针留出一些字节的内存。它被放在
堆上
,在那里它无法访问,并且它不会从
堆上下来,直到它是
空闲()
d或者在计算机上触发了内存清理,而这不是由用户控制的。因此,当你
free()
一个指针时,你基本上摆脱了指针和它指向的地址之间的关联,允许以后使用内存

既然如此,为什么
double
指针仍然指向相同的值

现在我想了想,为什么指针在
free()
s之后还有地址

由于我是
C
的初学者,我非常感谢所有的智慧和知识。谢谢你抽出时间

编辑:在进一步测试和干预之后,我发现如果您输入一个超过6位的数字,并在
双精度
的最后一位(如777.7777)上进行四舍五入,则在
自由()后,它将失去四舍五入

举例说明:

Before 'free()':
D: 0x8f2e038    777.778

After 'free()':
D: 0x8f2e038    777.777
这支持@rodrigo(在评论中)的假设,即由于
double
是8个字节,而不是
int
char
float
的4个字节-
free()
只修改前4个字节,因此不会丢失所有数据


谢谢大家的帮助

基本上,一旦释放指针,就不应该再使用它所指向的数据

malloc会为您分配一些负责写入和读取的内存块。那块“属于”你,但只是租金

释放该块后,它将返回到系统。如上所述,使用该数据是未定义的行为:预期结果(好像没有自由)、错误结果、崩溃

根据双重问题,尝试反转释放(D到A),看看会发生什么。。。(不管怎么说,马洛克不知道你打算在那个地方放一个替身)

我对malloc()和free()如何工作的理解是,当您将malloc()作为指针时,您会为指针留出一些字节的内存

你不需要一个指针。你需要一块内存。malloc返回的值是指向该内存的指针。让我们换个说法

我对malloc()和free()如何工作的理解是,当你malloc()一块内存时,你会留出一些字节的内存;指针返回指向该内存块的起始点

这个[内存块]被放在堆上

正确的;将堆视为长期随机访问存储

无法访问的位置

这要么是错误的,要么是荒谬的。哪些内容无法访问,哪些人无法访问

它[内存块]只有在空闲时才会离开堆

malloc分配的内存块保留供程序使用,直到调用
free
。要释放块,请调用free并传递最初从
malloc
返回的指针,yes

或者在计算机上触发内存清理,而这不是由用户控制的

这又是不连贯的。现代操作系统使用虚拟内存。当进程被破坏时,整个虚拟地址空间消失

释放()指针时,基本上可以消除指针与其指向的地址之间的关联,从而允许以后使用该内存

不,不,这是你误解的症结所在

通过将malloc最初返回的指针传递给free,可以释放内存块。这样就释放了内存块,如果进程中的其他代码需要内存,那么malloc就可以再次分配内存

但是free不会改变指针指向的地址!指针继续指向一个地址;那个地址现在无效了!在C语言中,取消对无效内存的引用被称为“未定义行为”,实际上任何事情都可能发生。你的程序可能会崩溃。您可以获得以前在那里的值。你的密码可以通过电子邮件发送给北极秘密巢穴中的黑客。任何事情都有可能发生,所以不要那样做

(巧合的是,我今天早些时候写了一篇关于这个主题的博客文章,文章将在周三发表,所以请关注我的博客以了解详细信息。)

既然如此,为什么双指针仍然指向相同的值

未定义的行为意味着任何事情都可能发生。指针仍然指向同一个值是正在发生的事情,而正在发生的事情是正在发生的事情的子集

现在我想起来了,为什么指针在free()之后还有地址呢

指针存储在变量中您没有更改变量的值。变量保留其值,直到您更改它们为止

我在哪里可以读更多

这个高度相关的问题可能会引起您的兴趣

这个问题与您的问题相同,只是在给定的问题中,指针指向堆栈,而不是堆。但逻辑是一样的:取消对弹出堆栈的指针引用