为了账号安全,请及时绑定邮箱和手机立即绑定

请问malloc怎么也初始化地址为0??free(A)只释放A[0] realloc也有问题???有截图

请问malloc怎么也初始化地址为0??free(A)只释放A[0] realloc也有问题???有截图

asdhjhg 2017-05-15 15:33:33
请问malloc怎么也初始化地址为0??free(A)只释放A[0] realloc增加的内存地址第一个是随机的后面都是初始化0???有截图malooc和calloc初始化肯定不一样啊,一个随机的比如分配的地址是 -17891602,而calloc是初始化为0的 地址应该是 0,不明白上面怎么执行的不对?free的问题,难道是因为指针A返回的value是内存中第一个地址的缘故?所以free只在第一个地址位置随机分配?我感觉整个人都不好了。。。。。还有realloc也是这问题,增加了双倍内存,然后增加部分的内存第一个地址是随机的,后面都是0 郁闷啊!!!大神来救我!!!#include <stdio.h> #include <stdlib.h> int main() {   int n;   printf ("Enter size of array\n");   scanf("%d",&n);   int *A = (int*)calloc(n,sizeof(int));   /*   for(int i=0; i<n; i++)   {     A[i] = i+1;   }   free(A);   */   //A = NULL;//It is a good practice to set pointer address as NULL after call to free. NULL is a macro for address 0 is and it cannot be dereferenced. The code below this statement will now cause a crash.   for(int i=0; i<n; i++)   {     printf ("%d\n", A[i]);   } }
查看完整描述

1 回答

已采纳
?
onemoo

TA贡献883条经验 获得超454个赞

不要混淆了“地址”和“地址中的内容”,这是两码事!

把内存当作“一连串的房间”的话,“内存地址”是房号,而“地址中的内容”是房间里的东西。指针类型中存储的就是地址。

  • “malloc怎么也初始化地址为0?”

    malloc 会分配一段指定大小的内存,但不会初始化其中的内容,或者说其中的值是随机的

    第 1 张图中你用 malloc 分配了 10 个 int 大小的空间,你可以把这段空间当作是 int A[10] 数组。然后你打印了这个“数组A”中的 10 个元素的值。

    在你这个结果中,碰巧这 10 个元素的值都是 0。 注意是“地址中的值为 0”,不是“地址为 0”。

    还有,不要因为看到都是 0 就觉得“malloc 难道也会将分配的地址中的值初始化为 0!?”,这只是碰巧了而已。

  • 第 2 张图中,你用 calloc 分配了 10 个 int 大小的空间。和 malloc 不同,calloc 会将其内容初始化为 0

    所以这次打印出的内容肯定都是 0 。

  • 第 3 张图,free(A) 并非只释放 A[0]。 free 释放的就是 A 指针所指的、之前由 malloc 所分配到的全部内存。重要的一点是:free 一个指针之后,再访问该指针的结果是未定义的

    所以不要再通过 A 测试那些内存中的值了,它们可能是任何值。

    记住:一旦 free 了某个指针,除非再给该指针赋予有意义的新地址,否则不要再按照原值使用该指针了。

  • 第 4 张图,realloc 会“重分配”之前分配到的内存,同时调整内存的大小,并且尽可能保留原内存中的值。当新内存大于原内存时,多出来的内存中的值是未定义的,也就是说多出来的内存中的值是随机的

    所以你的结果中,多出来的 135145、0、0、0、0 都是随机值。和前面的例子一样,只不过是碰到 0 比较多而已,并非是“后面初始化为 0”。

    另外说一下:其实 realloc 并不保证新内存肯定在原内存的位置上分配,它只保证新内存中保留原内存中的值。 在你的这个例子中,你打印了 A 和 B 的值,你可以看到它们确实是同一个地址,也就是说这一次 realloc 确实是在原内存位置上分配新内存的。


其实你不用想这么多。在初学阶段,你只要记住这些函数的行为,然后按照它们的规则使用这些函数即可。尤其是对于那些“未定义行为”,记住永远不要写依赖于“未定义行为”的代码就好了。 当看到了“未定义行为”,初学时不用绞尽脑汁想“为什么是这样的呀??”,因为 C 语言标准已经告诉你了这些行为是未定义的,所以出现什么样的情况都有可能。

当然了,虽说是“未定义行为”,到底还是有一定的原因造成你所看到的结果的。是的没错,当你足够通晓 C 语言之后,自然会明白为什么你看到的“未定义行为”表现出这样或那样的结果。 只不过不要在初学时(尤其是在没有人指导时)就想这些,因为你很可能会加入很多错误的“脑补”,这反而会造成你理解错误(你发的这个问题就是如此啊)!

查看完整回答
2 反对 回复 2017-05-18
  • asdhjhg
    asdhjhg
    非常感谢!我已经理解了!但是你说的在初学阶段,你只要记住这些函数的行为,然后按照它们的规则使用这些函数即可。但是我有强迫症。。。。。我会用了,就是知道how不知why我经常会抓狂。。。。总有种被控制住的感觉。所以,我还是会想whywhywhy。。。。。
  • onemoo
    onemoo
    这很正常,并且其实是好事,这表示你保持了很好的好奇心和探索欲。但正如我之前所说,错误的脑补可能会大大地误导你,纠缠于你当前无法理解的错误反而会降低学习效率,还不如按部就班地学,学到深入之后这些你就都能理解了。 再说个题外的,这就是为什么科班学生或有老大带的人能进步得很快的原因,即便是在初学阶段,当他们有这样的疑惑时,老师或大佬就能帮他们解答,这样能迅速精进功力啊...
  • onemoo
    onemoo
    所以如果没人指导你,而你又遇到让你钻牛角尖的问题的话,就在这里发问吧。 虽然这里的回答水平参差不齐,但应该还是能碰到让你满意的回答的...吧。 啊,刚意识到,你又会Linux又会python,不算是完全的初学者,那你学习C应该不会遇到太大的困难的
点击展开后面7
  • 1 回答
  • 1 关注
  • 2729 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信