| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1123 人关注过本帖, 1 人收藏
标题:使用realloc分配不成功,同时加free提示triggered a breakpoint. 请问这是什 ...
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
指针访问数据,有两个对象,一个是数据本身,是必须先存在的,另一个是指针,用于指向数据,故用指针的程序,实际上占用更多的内存。指针犹如一个指示棒(本来指针的英文单词pointer就是教师用的棒子),要指向某个东西,首先那个东西必须存在,另外,棒子与被指向的东西是两回事,不能等同。很多新手,总是以为声明了一个指针,就可以当数据用,比如int* x之后,就以为*p是一个int数据,写出*p = 1这类代码,殊不知此时p所指向的对象不存在,*p也就无从解引用,此时赋值,当然程序崩溃。为了使用指针,必须先声明int y,即有了数据对象,可以被指向,然后再使用一个指针变量(用了两份变量)去指向它,即int* x = &y,这样两个步骤之后,才可以用*x = 1赋值,这样等价于y = 1,实际上是脱裤子放屁,很简单的直接y = 1不用,偏要用两个变量做同一件事,直接访问变成间接访问,效率反而低了,逻辑也绕圈圈了,清晰明白的变成故弄玄虚了,却有人总爱做这样的题目,自以为在学用指针。指针不是那么用的,该在什么场合下用,见上一楼。原则无非是两个:一,只有在无法用y变量名访问空间的时候,才用指针;二,能够不用指针,就尽量不用指针。

授人以渔,不授人以鱼。
2015-09-14 04:19
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
想问一下你是怎么把代码贴上去的啊,我每次都是直接粘贴的,没你那种效果啊
2015-09-14 13:15
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 10楼 TonyDeng
谢谢! 大体看明白了,后面的realloc()是视频讲解的时候老师说了不详细说,只用画笔随便说了下,没说得太明白,后来看了前面的回帖去查了下就明白了。

第二段也解释了疑惑,就是对于访问动态数组的入口仅仅只有那个首地址,同时存在堆栈的区别,栈一般都有变量名,那么数组就应该属于栈,动态数组就属于堆。
但查了下堆栈,堆是先进先出,由系统控制,栈是先进后出,像一个玻璃杯进水,由程序员控制。
然而在视频中说的是数组是不能由程序员释放,不能更改数组大小等等,先不论堆栈的数据结构问题,只说其中的堆由系统控制(按第二段理解是:动态数组,不存在变量名的属于堆),栈由程序员控制(数组),这样说来存在矛盾了,数组我无法控制,但百科说是由程序员控制,堆我能控制却是由系统控制。不知道怎样才是正确的。

其他的地方都看懂了,试着总结如下:

1.只输出4字节大小的原因:
    sizeof是求对象尺寸的,而在sizeof(*pArr)的语句里面,由于已经声明为int*,即指向的对象为int型,则sizeof求的只会是int的大小,也就是4,而且由于动态数组的入口只有这一个,其他空间也没有变量名(pArr[i]不知道算不算),所以最终还是无法输出动态数组的大小。

2.崩溃的原因:
    使用free崩溃是由于使用realloc()已经改变了首空间的地址,此时再去free已经失效的原地址(即野指针)就会崩溃。

3.有两个危险的地方要注意:
    一个是realloc()扩张有可能改变首地址
    二是同时用几个变量储存一个动态地址的危险
2015-09-14 13:23
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 11楼 TonyDeng
学习了!  但“只有在无法用y变量名访问空间的时候,才用指针;”,这句没明白,是指的从别的函数利用指针去修改主函数的变量y吗,访问空间不明白是什么意思
2015-09-14 13:29
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 12楼 令狐少侠56
在编辑栏那里有一列功能,里面有个代码的功能,你点一下然后把代码内容放在code标签内就可以了
2015-09-14 13:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:8 
这里的堆和栈,不是数据结构的那种概念,虽然有些管理手段相似,但概念不是按那个分的。对内存空间而言,栈是程序内部自己管理的,就如是你的家,家里的范围,尽管小,但触手可及,储存快速方便。堆是外部不归自己管理的,就如是家外面的世界,有一个公共管理机构管理公共资源,你祗能向这个机构申请使用权,使用资源的时候,也是发出请求,对方响应,然后你得到所需要的信息,如此不断交互,总之不是你自己直接管理,资源的归还也不归你管。家里的资源在近,公共资源在远,近的可以就地取材,远的祗能遥指、用望远镜看,要向遥远的东西做动作,也得请人跑腿,那就是指针的作用。世界的资源不是你一个人(程序)独占的,按操作系统的管理方式,这种资源就不给你变量名,你祗能用指针访问。指针通常用在这些资源上的。栈上的数据,其实很少需要使用指针的,唯一的例外是数组传递,由于数组的尺寸可能比较大,在函数间传递如果复制数据的话开销也大,于是针对这种数据,就不复制了,而是改为复制地址,这就是数组传参蜕化为指针的实质。

用指针指向的空间,是不能通过sizeof()求得尺寸的,只有在栈上的数组,才可以用sizeof(数组名)获得数组的尺寸,这种特征,也是数组实际上不是指针的证据。数组就是数组,不是指针,反之亦然,然而在C语言中,数组的访问和指针访问的书写形式,可以互换,比如数组a[2]可以等价指针*(p+2),反之对指针也可以写成p[2]取得第3个元素的值,这才是通常说数组和指针可以互换的意思,不是说数组真的就是指针。通过malloc()申请的堆空间,在标准中,是没有机制返回空间尺寸的,但是由于这种申请是你自己主动发出的,申请多大肯定自己知道,那个值完全可以自己记忆下来,用不着别人反馈给你。在微软的扩展中,有一个非标函数返回这个值,其实它也是把申请时的信息复制存储起来罢了,也是你申请多少它返回多少。但实际上这种堆空间所占用的尺寸,通常比申请的要大,内存管理程序别有用途,那细节是你不需要知道的,但要一点要知道的,就是malloc()一个int数据所占用的堆空间,远远比在栈上一个int的空间大,所以不要用malloc()逐个逐个申请小数据,尤其是很多学生常用的用int型结点做链表,所浪费的资源和低效,完全逆着本意来。

[ 本帖最后由 TonyDeng 于 2015-9-14 21:25 编辑 ]

授人以渔,不授人以鱼。
2015-09-14 20:51
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
函数的传参,任何时候都是值复制,要么是复制数据本身,要么是复制地址。所谓的指针传参,实际上也是复制了一份指针,需知指针也是一个普通的变量,同样是复制它的值过去,祗不过这样的值代表地址罢了。

授人以渔,不授人以鱼。
2015-09-14 21:11
uswood
Rank: 2
等 级:论坛游民
帖 子:34
专家分:16
注 册:2014-3-29
收藏
得分:0 
回复 16楼 TonyDeng
懂了,感谢!受用很大  谢谢!
2015-09-14 21:18
快速回复:使用realloc分配不成功,同时加free提示triggered a breakpoint. 请问 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016351 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved