释放指向'double'值的指针

Jas*_*per 2 c free double pointers memory-management

我能找到的所有关于释放'双'指针的东西都指的是释放指针的指针,这不是我所说的.我已经想出了如何做到这一点.

它甚至可能不是一个大的事情在所有,但我注意到,当我free()一个int,charfloat指针,价值被删除或垃圾值替换,但是当我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;
}
Run Code Online (Sandbox Code Playgroud)

这产生了以下输出:

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
Run Code Online (Sandbox Code Playgroud)

这是正常的吗?我对如何malloc()free()工作的理解是,当你malloc()指针时,你为指针指向了一些内存字节.这是在heap无法访问的地方放置的,并且在计算机上触发内存清理heap之前它不会脱落free(),而不是由用户控制.因此,当你free()指针时,你基本上摆脱了指针和它指向的地址之间的关联,允许稍后使用该内存.

鉴于这一切,为什么double指针仍然指向相同的值?

现在我考虑一下,为什么指针在free()s 之后根本就有一个地址?

由于我是初学者C,所以非常感谢任何和所有的智慧和知识.感谢您的时间.

编辑:经过进一步的测试和干预后,我发现如果你输入一个数字超过6位并在最后一个数字上向上舍入(例如777.7777)的数字double,那么free()它就会失去它的四舍五入.

为了显示:

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

After 'free()':
D: 0x8f2e038    777.777
Run Code Online (Sandbox Code Playgroud)

这支持@罗德里戈的假设(的意见)认为,因为double是8个字节-相对于int,charfloat的4个字节- free()仅修改了前4个字节,所以它不会失去它的所有数据.

谢谢大家的帮助!

Eri*_*ert 7

我对malloc()和free()如何工作的理解是,当你使用malloc()一个指针时,你会为指针指向一些内存字节.

你没有malloc指针.你malloc一块内存.malloc返回的值是指向该内存的指针.所以让我们重新说一下.

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

正确.

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

正确; 将堆视为长期随机存取存储.

它无法访问的地方

这要么是错误的,要么是荒谬的.哪里有什么不能被访问,以及由谁来?

它[内存块]不会从堆中掉出来,直到它被释放()d

malloc分配的内存块保留用于程序的使用,直到free被调用.要释放块,可以调用free并传递最初返回的指针malloc,是的.

或者在计算机上触发内存清理,不受用户控制

这又是不连贯的.现代操作系统使用虚拟内存.当一个进程被销毁时,整个虚拟地址空间就会消失.

当你释放()指针时,你基本上摆脱了指针和它指向的地址之间的关联,允许以后使用该内存.

不不不不不.这是你误解的关键.

通过将malloc最初返回的指针传递给free来释放内存块.这释放了内存块,然后允许malloc再次将其移出,如果进程中的其他代码要求内存.

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

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

鉴于这一切,为什么双指针仍然指向相同的值?

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

现在我想一想,为什么指针在free()之后都有一个地址呢?

指针存储在变量中.您没有更改变量的值.变量保持其值,直到您更改它们.

我在哪里可以阅读更多?

您可能会对这个高度相关的问题感兴趣.

可以在其范围之外访问局部变量的内存吗?

这个问题和你的一样,除了在给定的问题中,指针指向堆栈,而不是指向堆.但逻辑是相同的:取消引用指向弹出堆栈帧的指针是未定义的行为,就像取消引用指向freed块的指针是未定义的行为一样.任何事情都可能发生.